Index pandas DataFrame par numéro de colonne, lorsque les noms de colonne sont entiers

j'essaie de garder juste certaines colonnes d'une DataFrame, et cela fonctionne bien quand les noms de colonnes sont des chaînes:

In [2]: import numpy as np

In [3]: import pandas as pd

In [4]: a = np.arange(35).reshape(5,7)

In [5]: df = pd.DataFrame(a, ['x', 'y', 'u', 'z', 'w'], ['a', 'b', 'c', 'd', 'e', 'f', 'g'])

In [6]: df
Out[6]: 
    a   b   c   d   e   f   g
x   0   1   2   3   4   5   6
y   7   8   9  10  11  12  13
u  14  15  16  17  18  19  20
z  21  22  23  24  25  26  27
w  28  29  30  31  32  33  34

[5 rows x 7 columns]

In [7]: df[[1,3]] #No problem
Out[7]: 
    b   d
x   1   3
y   8  10
u  15  17
z  22  24
w  29  31

cependant, quand les noms de colonne sont entiers, je reçois une erreur clé:

In [8]: df = pd.DataFrame(a, ['x', 'y', 'u', 'z', 'w'], range(10, 17))

In [9]: df
Out[9]: 
   10  11  12  13  14  15  16
x   0   1   2   3   4   5   6
y   7   8   9  10  11  12  13
u  14  15  16  17  18  19  20
z  21  22  23  24  25  26  27
w  28  29  30  31  32  33  34

[5 rows x 7 columns]

In [10]: df[[1,3]]

résultats dans:

KeyError: '[1 3] not in index'

je peux voir pourquoi pandas ne permet pas que -> pour éviter la confusion entre l'indexation par noms de colonne et numéros de colonne. Cependant, y a-t-il un moyen de dire aux pandas que je veux indexer par numéros de colonne? Bien sûr, une solution consiste à convertir les noms de colonnes en chaînes, mais je me demande s'il y a une meilleure solution.

5
demandé sur Akavall 2014-11-26 21:19:31

2 réponses

C'est exactement le but de lci , voir ici

In [37]: df
Out[37]: 
   10  11  12  13  14  15  16
x   0   1   2   3   4   5   6
y   7   8   9  10  11  12  13
u  14  15  16  17  18  19  20
z  21  22  23  24  25  26  27
w  28  29  30  31  32  33  34

In [38]: df.iloc[:,[1,3]]
Out[38]: 
   11  13
x   1   3
y   8  10
u  15  17
z  22  24
w  29  31
8
répondu Jeff 2014-11-26 21:13:32

c'est certainement une de ces choses qui ressemble à un bug mais qui est vraiment une décision de conception (je pense).

Un peu de travail autour des options:

renommer les colonnes avec leurs positions comme leur nom:

 df.columns = arange(0,len(df.columns))

une autre façon est d'obtenir des noms de df.columns :

print df[ df.columns[[1,3]] ]
   11  13
x   1   3
y   8  10
u  15  17
z  22  24
w  29  31

je pense que c'est le plus attrayant car il suffit d'ajouter un petit peu de code et de ne pas changer une colonne nom.

2
répondu JD Long 2014-11-26 18:29:56