Pandas chaque nième rangée

108

Dataframe.resample () fonctionne uniquement avec les données de séries temporelles. Je ne peux pas trouver un moyen d'obtenir chaque nième ligne à partir de données non chronologiques. Quelle est la meilleure méthode?

Mixel
la source

Réponses:

201

J'utiliserais iloc, qui prend une tranche de ligne / colonne, à la fois basée sur la position entière et suivant la syntaxe Python normale.

df.iloc[::5, :]
chrisb
la source
46
Pour ceux qui voudraient, par exemple, chaque cinquième ligne, mais à partir de la deuxième ligne, ce serait le cas df.iloc[1::5, :].
Little Bobby Tables
17
Vous pouvez omettre la partie colonne:df.iloc[::5]
joctee
1
@chrisb comment spécifier la ligne de départ? comme tous les 5 rangs, à partir de la deuxième rangée?
FabioSpaghetti le
30

Bien que la réponse acceptée par @ chrisb réponde à la question, j'aimerais y ajouter ce qui suit.

Une méthode simple que j'utilise pour obtenir les nthdonnées ou supprimer la nthligne est la suivante:

df1 = df[df.index % 3 != 0]  # Excludes every 3rd row starting from 0
df2 = df[df.index % 3 == 0]  # Selects every 3rd raw starting from 0

Cet échantillonnage basé sur l'arithmétique a la capacité de permettre des sélections de lignes encore plus complexes.

Cela suppose , bien sûr, que vous ayez une indexcolonne d' entiers ordonnés, consécutifs, commençant à 0.

métastableB
la source
6
ce n'est pas une bonne réponse car fait trois hypothèses, qui ne sont souvent pas satisfaites: (1) l'indice est numérique (2) l'indice il commence à zéro (3) les valeurs d'indice sont consécutives ... la dernière est particulièrement importante puisque vous ne pouvez pas utiliser la méthode suggérée plus d'une fois sans réinitialiser l'index
Constantine
1
Je comprends ton raisonnement. Modifie la réponse pour rendre les hypothèses plus explicites .
metastableB
1
@Constantine encore, ne serait-ce pas plus rapide que l'autre solution car vous pouvez simplement ajouter un index?
Readler
8

Il existe une solution encore plus simple à la réponse acceptée qui implique l'invocation directe df.__getitem__.

df = pd.DataFrame('x', index=range(5), columns=list('abc'))
df

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Par exemple, pour obtenir toutes les 2 lignes, vous pouvez faire

df[::2]

   a  b  c
0  x  x  x
2  x  x  x
4  x  x  x

Il y a aussi GroupBy.first/ GroupBy.head, vous groupez sur l'index:

df.index // 2
# Int64Index([0, 0, 1, 1, 2], dtype='int64')

df.groupby(df.index // 2).first()
# Alternatively,
# df.groupby(df.index // 2).head(1)

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x

L'indice est divisé par le sol par la foulée (2, dans ce cas). Si l'index n'est pas numérique, faites plutôt

# df.groupby(np.arange(len(df)) // 2).first()
df.groupby(pd.RangeIndex(len(df)) // 2).first()

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x
cs95
la source
1

J'avais une exigence similaire, mais je voulais le nième article dans un groupe particulier. Voilà comment je l'ai résolu.

groups = data.groupby(['group_key'])
selection = groups['index_col'].apply(lambda x: x % 3 == 0)
subset = data[selection]
Steztric
la source