Question Sélection de colonnes dans un dataframe de pandas


J'ai des données dans différentes colonnes mais je ne sais pas comment l'extraire pour l'enregistrer dans une autre variable.

index  a   b   c
1      2   3   4
2      3   4   5

Comment puis-je sélectionner 'b', 'c' et enregistrez-le dans df1?

j'ai essayé

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']

Aucun ne semble fonctionner.


518
2017-07-01 21:03


origine


Réponses:


Les noms de colonnes (qui sont des chaînes) ne peuvent pas être découpés comme vous avez essayé.

Ici, vous avez quelques options. Si vous savez à partir du contexte quelles variables vous voulez découper, vous pouvez simplement retourner une vue de seulement ces colonnes en passant une liste dans le __getitem__ syntaxe (les []).

df1 = df[['a','b']]

Alternativement, s'il est important de les indexer numériquement et non par leur nom (disons que votre code devrait le faire automatiquement sans connaître le nom des deux premières colonnes), vous pouvez le faire à la place:

df1 = df.iloc[:,0:2] # Remember that Python does not slice inclusive of the ending index.

De plus, vous devriez vous familiariser avec l'idée d'une vue dans un objet Pandas par rapport à une copie de cet objet. La première des méthodes ci-dessus retournera une nouvelle copie en mémoire du sous-objet désiré (les tranches désirées).

Parfois, cependant, il y a des conventions d'indexation dans Pandas qui ne le font pas et qui vous donnent une nouvelle variable qui fait juste référence au même morceau de mémoire que le sous-objet ou la tranche dans l'objet original. Cela se produira avec la deuxième façon d'indexation, de sorte que vous pouvez le modifier avec le copy() fonction pour obtenir une copie régulière. Lorsque cela se produit, changer ce que vous pensez être l'objet en tranches peut parfois modifier l'objet original. Toujours bon d'être à l'affût pour ça.

df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df

838
2017-07-02 02:43



En supposant que vos noms de colonnes (df.columns) sont ['index','a','b','c'], alors les données que vous voulez sont dans le 3ème et 4ème colonnes. Si vous ne connaissez pas leur nom lorsque votre script s'exécute, vous pouvez le faire

newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.

Comme le souligne EMS dans sa réponse, df.ix tranches de colonnes un peu plus concis, mais le .columns L'interface de découpage peut être plus naturelle car elle utilise la syntaxe d'indexation / découpage de la liste de python 1-D de vanille.

PRÉVENIR: 'index' est un mauvais nom pour un DataFrame colonne. Cette même étiquette est également utilisée pour le vrai df.index attribut, un Index tableau. Donc, votre colonne est retournée par df['index'] et l'index réel DataFrame est retourné par df.index. Un Index est un genre particulier de Series optimisé pour la recherche des valeurs de ses éléments. Pour df.index, il s'agit de rechercher des lignes par leur étiquette. Cette df.columns attribut est également un pd.Index tableau, pour rechercher des colonnes par leurs étiquettes.


67
2017-10-31 18:57



À partir de la version 0.11.0, colonnes peut être tranché de la manière que vous avez essayé d'utiliser le .loc indexeur:

df.loc[:, 'C':'E']

renvoie les colonnes C par E.


Une démo sur un DataFrame généré aléatoirement:

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 6)), 
                  columns=list('ABCDEF'), 
                  index=['R{}'.format(i) for i in range(100)])
df.head()

Out: 
     A   B   C   D   E   F
R0  99  78  61  16  73   8
R1  62  27  30  80   7  76
R2  15  53  80  27  44  77
R3  75  65  47  30  84  86
R4  18   9  41  62   1  82

Pour obtenir les colonnes de C à E (notez que contrairement au découpage d'entier, 'E' est inclus dans les colonnes):

df.loc[:, 'C':'E']

Out: 
      C   D   E
R0   61  16  73
R1   30  80   7
R2   80  27  44
R3   47  30  84
R4   41  62   1
R5    5  58   0
...

Même chose pour sélectionner des lignes en fonction des étiquettes. Obtenez les lignes 'R6' à 'R10' à partir de ces colonnes:

df.loc['R6':'R10', 'C':'E']

Out: 
      C   D   E
R6   51  27  31
R7   83  19  18
R8   11  67  65
R9   78  27  29
R10   7  16  94

.loc accepte également un tableau booléen afin que vous puissiez sélectionner les colonnes dont l'entrée correspondante dans le tableau est True. Par exemple, df.columns.isin(list('BCD')) résultats array([False, True, True, True, False, False], dtype=bool) - Vrai si le nom de la colonne est dans la liste ['B', 'C', 'D']; Faux, sinon.

df.loc[:, df.columns.isin(list('BCD'))]

Out: 
      B   C   D
R0   78  61  16
R1   27  30  80
R2   53  80  27
R3   65  47  30
R4    9  41  62
R5   78   5  58
...

54
2018-04-30 12:39



In [39]: df
Out[39]: 
   index  a  b  c
0      1  2  3  4
1      2  3  4  5

In [40]: df1 = df[['b', 'c']]

In [41]: df1
Out[41]: 
   b  c
0  3  4
1  4  5

48
2017-07-08 17:55



Je me rends compte que cette question est assez ancienne, mais dans la dernière version des pandas, il y a un moyen facile de faire exactement cela. Noms de colonne (qui sont des chaînes) pouvez être coupé de la manière que vous voulez.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)

34
2018-02-04 14:05



Vous pouvez fournir une liste de colonnes à supprimer et renvoyer le DataFrame avec uniquement les colonnes nécessaires à drop() fonctionne sur un DataFrame Pandas.

Juste dire

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)

retournerait un DataFrame avec juste les colonnes b et c.

le drop la méthode est documentée ici.


14
2017-09-03 11:30



J'ai trouvé cette méthode très utile:

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]

Plus de détails peuvent être trouvés ici


12
2018-05-02 09:41



il suffit d'utiliser: il sélectionnera la colonne b et c.

df1=pd.DataFrame()
df1=df[['b','c']]

alors vous pouvez simplement appeler df1:

df1

8
2017-11-10 09:35



Si vous voulez obtenir un élément par l'index de la ligne et le nom de la colonne, vous pouvez le faire comme df['b'][0]. C'est aussi simple que possible.

Ou vous pouvez utiliser df.ix[0,'b'], utilisation mixte de l'index et de l'étiquette.


3
2018-01-03 07:56