Sélection d'une ligne de séries / trames de données pandas par index entier

395

Je suis curieux de savoir pourquoi df[2]n'est pas pris en charge, tandis que df.ix[2]et les df[2:3]deux fonctionnent.

In [26]: df.ix[2]
Out[26]: 
A    1.027680
B    1.514210
C   -1.466963
D   -0.162339
Name: 2000-01-03 00:00:00

In [27]: df[2:3]
Out[27]: 
                  A        B         C         D
2000-01-03  1.02768  1.51421 -1.466963 -0.162339

Je m'attendrais df[2]à travailler de la même manière que df[2:3]pour être cohérent avec la convention d'indexation Python. Existe-t-il une raison de conception pour ne pas prendre en charge l'indexation des lignes par un seul entier?

cs95
la source
4
df.ix[2]ne fonctionne pas - du moins paspandas version '0.19.2'
Zahra
9
Pour voir la différence entre la sélection de lignes et de colonnes via l'opérateur d'indexation [], consultez cette réponse ci-dessous . Aussi NE JAMAIS UTILISER .ix, il est obsolète
Ted Petrou

Réponses:

552

faisant écho à @HYRY, voir les nouveaux documents en 0.11

http://pandas.pydata.org/pandas-docs/stable/indexing.html

Ici, nous avons de nouveaux opérateurs, .ilocexplicitement ne supporte que l'indexation entière et .locexplicite ne supporte que l'indexation d'étiquette

par exemple imaginez ce scénario

In [1]: df = pd.DataFrame(np.random.rand(5,2),index=range(0,10,2),columns=list('AB'))

In [2]: df
Out[2]: 
          A         B
0  1.068932 -0.794307
2 -0.470056  1.192211
4 -0.284561  0.756029
6  1.037563 -0.267820
8 -0.538478 -0.800654

In [5]: df.iloc[[2]]
Out[5]: 
          A         B
4 -0.284561  0.756029

In [6]: df.loc[[2]]
Out[6]: 
          A         B
2 -0.470056  1.192211

[] coupe les lignes (par emplacement d'étiquette) uniquement

Jeff
la source
7
Et si vous vouliez les 2e ET 3e ET 4e rangées?
FaCoffee
1
vous pouvez simplement passer une liste d'indexeurs; les documents sont indiqués ci
Jeff
2
Quelqu'un at-il une justification pour ces noms? Je trouve cela difficile à retenir parce que je ne sais pas pourquoi les iloclignes et les locétiquettes sont.
kilojoules du
3
@kilojoules .ilocrecherche les choses par ordre dans l'index (par exemple .iloc[[2]]) est la deuxième "ligne" dans df. Cette ligne se trouve à l' emplacement de l' index4 . .locles recherche par leur valeur d'index. Alors peut-être "iloc" est comme "i" comme dans A[i]? :)
Jim K.
1
@Jeff - cela fonctionne très bien, mais que se passe-t-il lorsque vous souhaitez dupliquer une ligne de votre bloc de données, par exemple df.loc[-1] = df.iloc[[0]], et l'insérer? Le cadre est livré avec une colonne d'index ajoutée donnant une erreur ValueError: cannot set a row with mismatched columns (voir stackoverflow.com/questions/47340571/… )
Growler
63

L'objectif principal de l'opérateur d'indexation DataFrame []est de sélectionner des colonnes.

Lorsque l'opérateur d'indexation reçoit une chaîne ou un entier, il tente de trouver une colonne portant ce nom particulier et de la renvoyer en tant que série.

Donc, dans la question ci-dessus: df[2]recherche un nom de colonne correspondant à la valeur entière 2. Cette colonne n'existe pas et un KeyErrorest levé.


L'opérateur d'indexation DataFrame change complètement de comportement pour sélectionner des lignes lorsque la notation de tranche est utilisée

Étrangement, lorsqu'il reçoit une tranche, l'opérateur d'indexation DataFrame sélectionne des lignes et peut le faire par emplacement entier ou par étiquette d'index.

df[2:3]

Cela coupera à partir de la ligne avec l'emplacement entier 2 à 3, à l'exclusion du dernier élément. Donc, juste une seule rangée. Ce qui suit sélectionne les lignes commençant à l'emplacement entier 6 jusqu'à 20, sans y inclure, toutes les trois lignes.

df[6:20:3]

Vous pouvez également utiliser des tranches composées d'étiquettes de chaîne si votre index DataFrame contient des chaînes. Pour plus de détails, consultez cette solution sur .iloc vs .loc .

Je n'utilise presque jamais cette notation de tranche avec l'opérateur d'indexation car elle n'est pas explicite et presque jamais utilisée. Lorsque vous coupez en rangées, respectez .loc/.iloc.

Ted Petrou
la source
Essayer d'ajouter des lignes à une autre trame de données à l'aide de l'opérateur indxeing mais l'autre trame de données reste vide. Pourquoi?
FindOutIslamNow
23

Vous pouvez penser DataFrame comme un dict de Series. df[key]essayez de sélectionner l'index de colonne par keyet retourne un objet Series.

Cependant, trancher à l'intérieur de [] tranche les lignes, car c'est une opération très courante.

Vous pouvez lire le document pour plus de détails:

http://pandas.pydata.org/pandas-docs/stable/indexing.html#basics

HYRY
la source
Merci pour l'astuce. C'est drôle, ce genre de choses est ce qui fait que parfois les pandas s'interrogent. Ajouter des exceptions au comportement dans certaines situations, .. pour moi, c'est comme sacrifier la cohérence pour un peu de commodité.
Carl Berger
15

Pour accéder par index à la table pandas, on peut également envisager l' option numpy.as_array pour convertir la table en tableau Numpy en tant que

np_df = df.as_matrix()

et alors

np_df[i] 

travaillerait.

Pavel Prochazka
la source
11
qui va à l'encontre de l'objectif des index de dataframes et de tout ce que les pandas offrent d'autre
Fábio Dias
6

Vous pouvez jeter un œil au code source .

DataFramea une fonction privée _slice()pour trancher le DataFrame, et il permet au paramètre axisde déterminer quel axe couper. Le __getitem__()for DataFramene définit pas l'axe lors de l'appel _slice(). Donc, le _slice()couper par défaut par axe 0.

Vous pouvez faire une expérience simple, qui pourrait vous aider:

print df._slice(slice(0, 2))
print df._slice(slice(0, 2), 0)
print df._slice(slice(0, 2), 1)
Waitkuo
la source
5

vous pouvez parcourir la trame de données comme ceci.

for ad in range(1,dataframe_c.size):
    print(dataframe_c.values[ad])
user1401491
la source