Sélection d'une ligne de la série pandas/dataframe par index entier

je suis curieux de savoir pourquoi df[2] n'est pas supporté, alors que df.ix[2] et df[2:3] fonctionnent tous les deux.

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 à ce que df[2] fonctionne de la même manière que df[2:3] pour être compatible avec la convention d'indexation Python. Y a-t-il une raison de ne pas prendre en charge l'indexation ligne par entier?

259
demandé sur coldspeed 2013-04-19 07:14:00

6 réponses

en écho à @HYRY, voir les nouvelles docs de 0,11

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

ici, nous avons de nouveaux opérateurs, .iloc pour supporter explicitement l'indexation entière seulement, et .loc pour supporter explicitement l'indexation étiquette seulement

p. ex. 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

[] tranches les rangées (selon l'emplacement de l'étiquette) seulement

378
répondu Jeff 2018-06-05 12:40:37

le but principal de L'opérateur d'indexation DataFrame, [] est de sélectionner les colonnes.

lorsque l'opérateur d'indexation est passé à une chaîne ou à un entier, il tente de trouver une colonne avec ce nom particulier et de la retourner comme une 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 KeyError est déclenché.


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

étrangement, lorsqu'on lui donne une tranche, L'opérateur d'indexation DataFrame sélectionne les lignes et peut le faire par emplacement d'entier ou par étiquette d'index.

df[2:3]

coupe à partir de la ligne avec l'emplacement entier 2 jusqu'à 3, à l'exclusion du dernier élément. Donc, il suffit d'une seule ligne. La suivante sélectionne les lignes commençant à entier emplacement 6 jusqu'à 20 par chaque troisième ligne.

df[6:20:3]

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

Je n'utilise presque jamais cette notation de tranche avec l'opérateur d'indexation comme son non explicite et rarement utilisé. En tranchant par des rangées, coller avec .loc/.iloc .

24
répondu Ted Petrou 2017-11-05 19:41:40

vous pouvez penser DataFrame comme un dict de série. df[key] essayez de sélectionner l'index des colonnes par key et retourne un objet de série.

cependant découper à l'intérieur de [] coupe les rangées, parce que 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

19
répondu HYRY 2013-04-19 07:33:32

pour un accès indexé à la table de pandas, on peut aussi considérer numpy.as_array option pour convertir la table en tableau de Numpy comme

np_df = df.as_matrix()

et ensuite

np_df[i] 

marcherait.

10
répondu Pavel Prochazka 2016-05-23 06:53:06

vous pouvez faire une boucle à travers la base de données comme ceci .

for ad in range(1,dataframe_c.size):
    print(dataframe_c.values[ad])
5
répondu user1401491 2017-04-13 10:56:04

vous pouvez jeter un oeil au code source .

DataFrame a une fonction privée _slice() pour trancher le DataFrame , et il permet au paramètre axis de déterminer quel axe trancher. Le __getitem__() pour DataFrame ne fixe pas l'axe en invoquant _slice() . Ainsi le _slice() le tranche par défaut l'axe 0.

vous pouvez prendre 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)
4
répondu waitingkuo 2013-04-19 10:47:25