Lors de la sélection d' une seule colonne d'une trame de données pandas ( par exemple df.iloc[:, 0]
, df['A']
ou df.A
, etc), le vecteur résultant est automatiquement converti en une série au lieu d'une trame de données à colonne unique. Cependant, j'écris des fonctions qui prennent un DataFrame comme argument d'entrée. Par conséquent, je préfère traiter avec DataFrame à colonne unique au lieu de Series afin que la fonction puisse supposer que 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 un moyen plus élégant d'indexer directement à partir d'un DataFrame afin que le résultat soit un DataFrame à une seule colonne au lieu de Series?
92
Réponses:
Comme @Jeff le mentionne, il existe plusieurs façons de le faire, mais je recommande d'utiliser loc / iloc pour être plus explicite (et signaler les 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 toute ambiguïté dans le cas des noms de colonne entiers (précisément pourquoi loc / iloc a été créé). 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
la source
[]
rend le résultat unDataFrame
au lieu d'unSeries
, mais où dans la documentation pandas ce type de syntaxe d'indexation est-il discuté? J'essaye juste d'obtenir le nom "officiel" de cette technique d'indexation pour que je la comprenne vraiment. Merci!Comme Andy Hayden le recommande, l'utilisation de .iloc / .loc pour indexer les cadres de données (à une seule colonne) est la voie à suivre; un autre point à noter est comment exprimer les positions d'index. Utilisez des étiquettes / positions d'index répertoriées tout en spécifiant les valeurs d'argument à indexer en tant que Dataframe; ne pas le faire renverra un 'pandas.core.series.Series'
Contribution:
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))
Production:
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'>
la source
Vous pouvez utiliser
df.iloc[:, 0:1]
, dans ce cas le vecteur résultant sera uneDataFrame
série et non une série.Comme vous pouvez le voir:
la source
Ces trois approches ont été évoquées:
pd.DataFrame(df.loc[:, 'A']) # Approach of the original post df.loc[:,[['A']] # Approach 2 (note: use iloc for positional indexing) df[['A']] # Approach 3
pd.Series.to_frame () est une autre approche.
Comme il s'agit d'une méthode, elle peut être utilisée dans des situations où les deuxième et troisième approches ci-dessus ne s'appliquent pas. En particulier, il est utile lorsque vous appliquez une méthode à une colonne de votre dataframe et que vous souhaitez convertir la sortie en dataframe au lieu d'une série. Par exemple, dans un Jupyter Notebook, une série n'aura pas une jolie sortie, mais une dataframe en aura.
# Basic use case: df['A'].to_frame() # Use case 2 (this will give you pretty output in a Jupyter Notebook): df['A'].describe().to_frame() # Use case 3: df['A'].str.strip().to_frame() # Use case 4: def some_function(num): ... df['A'].apply(some_function).to_frame()
la source