Sélection de plusieurs colonnes dans une base de données pandas

j'ai des données dans différentes colonnes mais je ne sais pas comment les extraire pour les sauvegarder dans une autre variable.

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

Comment puis-je sélectionner 'a' , 'b' et le sauvegarder dans df1?

j'ai essayé

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

Aucun ne semble fonctionner.

(Modification Mineure)

555
demandé sur RegressForward 2012-07-02 01:03:16

11 réponses

les noms de colonne (qui sont des chaînes) ne peuvent pas être tranchés de la manière que vous avez essayé.

voici quelques options. Si vous savez de contexte quelles variables vous voulez découper, vous pouvez simplement retourner une vue de seulement ces colonnes en passant une liste dans la syntaxe __getitem__ (les []'s).

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

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

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

en outre, vous devriez vous familiariser avec l'idée d'une vue dans un objet Pandas vs 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 ya des conventions d'indexation dans les Pandas qui ne font pas cela et à la place vous donner une nouvelle variable qui fait simplement référence au même morceau de mémoire que le sous-objet ou tranche dans l'objet original. Cela se produira avec la deuxième façon d'indexer, de sorte que vous pouvez le modifier avec la fonction copy() pour obtenir une copie régulière. Lorsque cela se produit, changer ce que vous pensez être l'objet tranché peut parfois modifier l'objet original. Toujours bon d'être à l'affût pour cela.

df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df
907
répondu ely 2017-10-17 23:25:11

en supposant que vos noms de colonne ( df.columns ) sont ['index','a','b','c'] , alors les données que vous voulez est dans le Les 3e et 4e colonnes. Si vous ne connaissez pas leurs noms quand 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 EMS le souligne dans sa réponse , df.ix tranches colonnes un peu plus concise, mais l'interface de tranchage .columns pourrait être plus naturel parce qu'il utilise la syntaxe vanille 1-D Python liste d'indexation/tranchage.

WARN: 'index' est un mauvais nom pour une colonne DataFrame . Cette même étiquette est également utilisée pour le véritable attribut df.index , un tableau Index . Ainsi votre colonne est retournée par df['index'] et le véritable index de DataFrame est retourné par df.index . Un Index est un type spécial de Series optimisé pour la recherche des valeurs de ses éléments. Pour df.indice c'est pour la recherche de lignes par leur étiquette. Cet attribut df.columns est aussi un tableau pd.Index , pour la recherche les colonnes par leurs étiquettes.

71
répondu hobs 2017-05-23 12:10:48

depuis la version 0.11.0, les colonnes peuvent être tranchés de la manière que vous avez essayé d'utiliser le .loc indexeur:

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

renvoie les colonnes C à E .


une démo sur Un générés aléatoirement DataFrame:

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 tranchage 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êmes travaux pour sélectionner des lignes basées sur 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 de sorte que vous pouvez sélectionner les colonnes dont l'entrée correspondante dans le tableau est True . Par exemple, df.columns.isin(list('BCD')) retourne array([False, True, True, True, False, False], dtype=bool) - vrai si le nom de la colonne est dans la liste ['B', 'C', 'D'] ; faux, autrement.

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
...
60
répondu ayhan 2017-04-29 16:14:38
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
50
répondu Wes McKinney 2012-07-08 17:55:12

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

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
34
répondu zerovector 2016-02-04 14:05:35

vous pouvez fournir une liste de colonnes à supprimer et retourner la DataFrame avec seulement les colonnes nécessaires en utilisant la fonction drop() sur une DataFrame Pandas.

il suffit de dire

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

retournerait une base de données avec seulement les colonnes b et c .

la méthode drop est documentée ici .

15
répondu Muthu Chithambara Jothi 2014-11-03 22:16:59

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

13
répondu Alvis 2018-04-02 18:38:13

il suffit d'utiliser: il sélectionnera les colonnes b et c.

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

alors vous pouvez simplement appeler df1:

df1
7
répondu Akash Nayak 2017-11-10 09:35:50

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

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

Note: depuis v0.20 ix a été déprécié en faveur de loc / iloc .

3
répondu W.Perrin 2018-08-09 14:38:55

les différentes approches discutées dans les réponses ci-dessus sont basées sur l'hypothèse que soit l'utilisateur sait les indices de colonne à laisser tomber ou sous-ensemble sur, ou l'Utilisateur souhaite sous-ensemble une base de données en utilisant une gamme de colonnes (par exemple entre 'C' : 'E'). pandas.DataFrame.drop () est certainement une option de sous-ensemble de données basée sur une liste de colonnes définies par l'utilisateur (bien que vous devez être prudent que vous utilisez toujours la copie de dataframe et inplace les paramètres ne doivent pas être définis à True !!)

une autre option est d'utiliser pandas.colonne.difference () , qui fait une différence définie sur les noms de colonne, et renvoie un type index de tableau contenant les colonnes désirées. La solution est la suivante:

df = pd.DataFrame([[2,3,4],[3,4,5]],columns=['a','b','c'],index=[1,2])
columns_for_differencing = ['a']
df1 = df.copy()[df.columns.difference(columns_for_differencing)]
print(df1)

la sortie serait: b c 1 3 4 2 4 5

2
répondu Harshit 2018-07-21 21:28:41

commençant par 0.21.0, en utilisant .loc ou [] avec une liste avec une ou plusieurs étiquettes manquantes, est déprécié, en faveur de .reindex . Donc, la réponse à votre question est:

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

dans les versions précédentes, en utilisant .loc[list-of-labels] fonctionnerait aussi longtemps qu'au moins une des clés a été trouvée (sinon il soulèverait un KeyError ). Ce comportement est déprécié et affiche maintenant un message d'avertissement. L'option recommandée est d'utiliser .reindex() .

plus d'informations à https://pandas.pydata.org/pandas-docs/stable/indexing.html#reindexing

0
répondu tozCSS 2018-08-15 18:13:41