web-dev-qa-db-fra.com

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

Je suis curieux de savoir pourquoi df[2] n'est pas pris en charge, 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 cohérent avec Python convention d'indexation. Existe-t-il une raison de conception pour ne pas prendre en charge l'indexation d'une ligne par un entier?

345
user1642513

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

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

Ici, nous avons de nouveaux opérateurs, .iloc pour supporter explicitement uniquement l'indexation d'entiers, et .loc pour supporter explicitement uniquement l'indexation d'étiquettes.

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

[] découpe les lignes en tranches uniquement

489
Jeff

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 la renvoie sous forme de série.

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


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

Bizarrement, l'opérateur d'indexation DataFrame sélectionne des lignes et peut le faire par emplacement entier ou par libellé d'index.

df[2:3]

Cela tranchera à 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’à moins de 20 toutes les 3 lignes.

df[6:20:3]

Vous pouvez également utiliser des tranches constituées d'étiquettes de chaîne si votre index DataFrame contient des chaînes. Pour plus de détails, voir 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 n’est pratiquement jamais utilisée. Lors du découpage par rangées, utilisez .loc/.iloc.

47
Ted Petrou

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

Toutefois, le découpage à l'intérieur de [] découpe les lignes en tranches, car il s'agit d'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

22
HYRY

Pour un accès indexé à la table pandas, on peut également envisager l'option numpy.as_array permettant de convertir la table en tableau Numpy en tant que

np_df = df.as_matrix()

puis

np_df[i] 

travaillerait.

13
Pavel Prochazka

Vous pouvez jeter un oeil au code source .

DataFrame a une fonction privée _slice() pour découper le DataFrame et permet au paramètre axis de déterminer quel axe doit être découpé. La __getitem__() pour DataFrame ne définit pas l'axe lors de l'appel de _slice(). Ainsi, la _slice() le coupe en tranches par défaut de l’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)
7
waitingkuo

vous pouvez parcourir le bloc de données comme ceci.

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