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

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

Comment sélectionner 'a', 'b' et l'enregistrer dans df1?

J'ai essayé

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

Aucun ne semble fonctionner.

1017
user1234440 2 juil. 2012 à 01:03

13 réponses

Meilleure réponse

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

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

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

Alternativement, s'il est important de les indexer numériquement et non par leur nom (par exemple, votre code devrait le faire automatiquement sans connaître les noms 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 devez 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 renverra une nouvelle copie en mémoire du sous-objet souhaité (les tranches souhaitées).

Parfois, cependant, il existe des conventions d'indexation dans Pandas qui ne le font pas et vous donnent à la place une nouvelle variable qui fait simplement référence au même bloc de mémoire que le sous-objet ou la tranche dans l'objet d'origine. Cela se produira avec la deuxième façon d'indexer, vous pouvez donc 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 découpé en tranches peut parfois altérer l'objet d'origine. C'est toujours bon d'être à l'affût.

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

Pour utiliser iloc, vous devez connaître les positions des colonnes (ou indices). Comme les positions des colonnes peuvent changer, au lieu d'index de codage en dur, vous pouvez utiliser iloc avec la fonction get_loc de la méthode columns de l'objet de trame de données pour obtenir les indices de colonne.

{df.columns.get_loc(c):c for idx, c in enumerate(df.columns)}

Vous pouvez maintenant utiliser ce dictionnaire pour accéder aux colonnes par le biais de noms et en utilisant iloc.

1624
Harshit 29 mars 2019 à 08:21

Vous pouvez utiliser des pandas. Je crée le DataFrame:

    import pandas as pd
    df = pd.DataFrame([[1, 2,5], [5,4, 5], [7,7, 8], [7,6,9]], 
                      index=['Jane', 'Peter','Alex','Ann'],
                      columns=['Test_1', 'Test_2', 'Test_3'])

Le DataFrame:

           Test_1  Test_2  Test_3
    Jane        1       2       5
    Peter       5       4       5
    Alex        7       7       8
    Ann         7       6       9

Pour sélectionner une ou plusieurs colonnes par nom:

    df[['Test_1','Test_3']]

           Test_1  Test_3
    Jane        1       5
    Peter       5       5
    Alex        7       8
    Ann         7       9

Vous pouvez aussi utiliser:

    df.Test_2

Et pour obtenir la colonne Test_2

    Jane     2
    Peter    4
    Alex     7
    Ann      6

Vous pouvez également sélectionner des colonnes et des lignes à partir de ces lignes à l'aide de .loc() . Cela s'appelle "découpage" . Notez que je passe de la colonne Test_1 à Test_3

    df.loc[:,'Test_1':'Test_3']

La "tranche" est:

            Test_1  Test_2  Test_3
     Jane        1       2       5
     Peter       5       4       5
     Alex        7       7       8
     Ann         7       6       9

Et si vous voulez simplement Peter et Ann des colonnes Test_1 et Test_3:

    df.loc[['Peter', 'Ann'],['Test_1','Test_3']]

Vous obtenez:

           Test_1  Test_3
    Peter       5       5
    Ann         7       9
9
pink.slash 20 févr. 2019 à 01:01

Les différentes approches discutées dans les réponses ci-dessus sont basées sur l'hypothèse que l'utilisateur sait que les indices de colonne doivent être supprimés ou sous-définis, ou que l'utilisateur souhaite sous-définir une trame de données en utilisant une plage de colonnes (par exemple entre 'C': 'E') . pandas.DataFrame.drop () est certainement une option pour sous-définir les données sur la base d'une liste de colonnes définies par l'utilisateur (bien que vous deviez faire attention à toujours utiliser une copie de dataframe et inplace les paramètres ne doivent pas être définis sur True !!)

Une autre option consiste à utiliser pandas.columns.difference () , qui fait une différence définie sur les noms de colonnes et renvoie un type d'index de tableau contenant les colonnes souhaitées. Voici la solution:

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: avant JC 1 3 4 2 4 5

4
Harshit 21 juil. 2018 à 21:28

Une approche différente et facile: itérer les lignes

Utiliser iterrows

 df1= pd.DataFrame() #creating an empty dataframe
 for index,i in df.iterrows():
    df1.loc[index,'A']=df.loc[index,'A']
    df1.loc[index,'B']=df.loc[index,'B']
    df1.head()
6
Saurabh 14 janv. 2020 à 03:01

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

18
Sylhare 2 avril 2018 à 18: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
62
Wes McKinney 8 juil. 2012 à 17:55

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

Je dis juste

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

Retournerait un DataFrame avec juste les colonnes b et c.

La méthode drop est documentée ici .

20
Alex Riley 3 nov. 2014 à 22:16

Depuis la version 0.21.0, l'utilisation de .loc ou [] avec une liste avec une ou plusieurs étiquettes manquantes est déconseillée au profit de .reindex. Donc, la réponse à votre question est:

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

Dans les versions précédentes, l'utilisation de .loc[list-of-labels] fonctionnait aussi longtemps qu'au moins 1 des clés était trouvée (sinon cela déclencherait un KeyError). Ce comportement est obsolète et affiche désormais un message d'avertissement. L'alternative recommandée consiste à utiliser .reindex().

En savoir plus sur Indexation et sélection de données

9
tozCSS 18 sept. 2019 à 14:35

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 imaginer.

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

Remarque: depuis la v0.20, ix est déconseillé au profit de loc / iloc.

7
jpp 9 août 2018 à 14:38

Vous pouvez également utiliser df.pop ()

>>> df = pd.DataFrame([('falcon', 'bird',    389.0),
...                    ('parrot', 'bird',     24.0),
...                    ('lion',   'mammal',   80.5),
...                    ('monkey', 'mammal', np.nan)],
...                   columns=('name', 'class', 'max_speed'))
>>> df
     name   class  max_speed
0  falcon    bird      389.0
1  parrot    bird       24.0
2    lion  mammal       80.5
3  monkey  mammal 

>>> df.pop('class')
0      bird
1      bird
2    mammal
3    mammal
Name: class, dtype: object

>>> df
     name  max_speed
0  falcon      389.0
1  parrot       24.0
2    lion       80.5
3  monkey        NaN

Faites le moi savoir si cela vous aide, veuillez utiliser df.pop (c)

3
cs95 7 avril 2019 à 22:27

Je me rends compte que cette question est assez ancienne, mais dans la dernière version de pandas, il existe un moyen facile de faire exactement cela. Les noms de colonne (qui sont des chaînes) peuvent être découpés comme vous le souhaitez.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
55
zerovector 4 févr. 2016 à 14:05

J'ai vu plusieurs réponses à ce sujet, mais je ne sais toujours pas. Comment choisiriez-vous ces colonnes d'intérêt? La réponse à cela est que si vous les avez rassemblés dans une liste, vous pouvez simplement référencer les colonnes en utilisant la liste.

Exemple

print(extracted_features.shape)
print(extracted_features)

(63,)
['f000004' 'f000005' 'f000006' 'f000014' 'f000039' 'f000040' 'f000043'
 'f000047' 'f000048' 'f000049' 'f000050' 'f000051' 'f000052' 'f000053'
 'f000054' 'f000055' 'f000056' 'f000057' 'f000058' 'f000059' 'f000060'
 'f000061' 'f000062' 'f000063' 'f000064' 'f000065' 'f000066' 'f000067'
 'f000068' 'f000069' 'f000070' 'f000071' 'f000072' 'f000073' 'f000074'
 'f000075' 'f000076' 'f000077' 'f000078' 'f000079' 'f000080' 'f000081'
 'f000082' 'f000083' 'f000084' 'f000085' 'f000086' 'f000087' 'f000088'
 'f000089' 'f000090' 'f000091' 'f000092' 'f000093' 'f000094' 'f000095'
 'f000096' 'f000097' 'f000098' 'f000099' 'f000100' 'f000101' 'f000103']

J'ai la liste suivante / tableau numpy extracted_features, spécifiant 63 colonnes. L'ensemble de données d'origine comporte 103 colonnes, et j'aimerais extraire exactement celles-ci, puis j'utiliserais

dataset[extracted_features]

Et vous vous retrouverez avec cela

enter image description here

C'est quelque chose que vous utiliseriez assez souvent dans Machine Learning (plus précisément, dans la sélection des fonctionnalités). Je voudrais également discuter d'autres façons, mais je pense que cela a déjà été couvert par d'autres stackoverflowers. J'espère que cela vous a été utile!

2
Kareem Jeiroudi 26 mai 2019 à 19:21

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

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

Est équivalent à

df[['C', 'D', 'E']]  # or df.loc[:, ['C', 'D', 'E']]

Et renvoie les colonnes C à 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'entiers, '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
...

Il en va de même pour la sélection de 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')) renvoie 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
...
115
ayhan 25 janv. 2019 à 11:12