web-dev-qa-db-fra.com

Python pandas: conserver la colonne sélectionnée en tant que DataFrame au lieu de Series

Lorsque vous sélectionnez une seule colonne dans un pandas DataFrame (disons df.iloc[:, 0], df['A'], Ou df.A, Etc.), le vecteur résultant est automatiquement converti en une série au lieu d'un DataFrame à une seule colonne. Cependant, j'écris certaines fonctions qui prennent un DataFrame comme argument d'entrée. Par conséquent, je préfère traiter un DataFrame à une seule colonne au lieu de la série afin que la fonction puisse supposer, par exemple, df .columns est accessible. À l'heure actuelle, je dois convertir explicitement la série en un DataFrame en utilisant quelque chose comme pd.DataFrame(df.iloc[:, 0]). Cela ne semble pas être la méthode la plus propre. Existe-t-il une manière plus élégante d'indexer à partir d'un DataFrame directement afin que le résultat soit un DataFrame à colonne unique au lieu de Series?

66
user1642513

Comme @Jeff le mentionne, il existe plusieurs façons de le faire, mais je recommande d'utiliser loc/iloc pour être plus explicite (et déclencher des erreurs tôt si vous essayez quelque chose d'ambigu):

In [10]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B'])

In [11]: df
Out[11]:
   A  B
0  1  2
1  3  4

In [12]: df[['A']]

In [13]: df[[0]]

In [14]: df.loc[:, ['A']]

In [15]: df.iloc[:, [0]]

Out[12-15]:  # they all return the same thing:
   A
0  1
1  3

Les deux derniers choix suppriment l'ambiguïté dans le cas des noms de colonne entiers (précisément pourquoi loc/iloc ont été créés). Par exemple:

In [16]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 0])

In [17]: df
Out[17]:
   A  0
0  1  2
1  3  4

In [18]: df[[0]]  # ambiguous
Out[18]:
   A
0  1
1  3
80
Andy Hayden

Comme Andy Hayden le recommande, utiliser .iloc/.loc pour indexer la trame de données (à une seule colonne) est la voie à suivre; un autre point à noter est de savoir comment exprimer les positions de l'indice. Utilisez un étiquettes/positions d'index répertoriées tout en spécifiant les valeurs d'argument à indexer en tant que Dataframe; dans le cas contraire, un "pandas.core.series.Series" sera renvoyé

Entrée:

    A_1 = train_data.loc[:,'Fraudster']
    print('A_1 is of type', type(A_1))
    A_2 = train_data.loc[:, ['Fraudster']]
    print('A_2 is of type', type(A_2))
    A_3 = train_data.iloc[:,12]
    print('A_3 is of type', type(A_3))
    A_4 = train_data.iloc[:,[12]]
    print('A_4 is of type', type(A_4))

Sortie:

    A_1 is of type <class 'pandas.core.series.Series'>
    A_2 is of type <class 'pandas.core.frame.DataFrame'>
    A_3 is of type <class 'pandas.core.series.Series'>
    A_4 is of type <class 'pandas.core.frame.DataFrame'>
0
Sumanth Lazarus