Extraction de colonnes sélectionnées spécifiques vers le nouveau DataFrame en tant que copie

185

J'ai un dataframe de pandas géants avec 4 colonnes et je veux créer une nouvelle trame de données qui ne possède trois des colonnes. Cette question est similaire à: Extraire des colonnes spécifiques d'une trame de données mais pas pour les pandas R. Le code suivant ne fonctionne pas, génère une erreur et n'est certainement pas la manière pandasnique de le faire.

import pandas as pd
old = pd.DataFrame({'A' : [4,5], 'B' : [10,20], 'C' : [100,50], 'D' : [-30,-50]})
new = pd.DataFrame(zip(old.A, old.C, old.D)) # raises TypeError: data argument can't be an iterator 

Quelle est la manière pandasnique de le faire?

SpeedCoder5
la source

Réponses:

359

Il existe un moyen de le faire et cela ressemble en fait à R

new = old[['A', 'C', 'D']].copy()

Ici, vous sélectionnez simplement les colonnes souhaitées dans le bloc de données d'origine et créez une variable pour celles-ci. Si vous souhaitez modifier le nouveau dataframe, vous voudrez probablement l'utiliser .copy()pour éviter un fichier SettingWithCopyWarning.

Une méthode alternative consiste à utiliser filterqui créera une copie par défaut:

new = old.filter(['A','B','D'], axis=1)

Enfin, en fonction du nombre de colonnes dans votre dataframe d'origine, il peut être plus succinct d'exprimer cela en utilisant un drop(cela créera également une copie par défaut):

new = old.drop('B', axis=1)
johnchase
la source
20
Une mise en garde si vous ne copiez qu'une colonne: Dans old[['A']].copy(), les doubles crochets sont nécessaires pour créer un nouveau bloc de données. Notez que old['A'].copy()cela ne créera qu'une série.
intotecho
19

Le moyen le plus simple est

new = old[['A','C','D']]

.

Stidmatt
la source
3
Cela ne fait pas de copie sauf si vous appelez explicitement .copy ()
Sylvain
ceci copie par défaut.
Nguai al
2
@Nguaial le comportement de l'indexation simple n'est pas spécifié. Vous ne saurez pas si vous obtenez une copie ou une vue. Voir la documentation pour plus de détails: pandas.pydata.org/pandas-docs/stable/user_guide
Ole Fass
8

Un autre moyen plus simple semble être:

new = pd.DataFrame([old.A, old.B, old.C]).transpose()

old.column_namevous donnera une série. Faites une liste de toutes les séries de colonnes que vous souhaitez conserver et transmettez-la au constructeur DataFrame. Nous devons faire une transposition pour ajuster la forme.

In [14]:pd.DataFrame([old.A, old.B, old.C]).transpose()
Out[14]: 
   A   B    C
0  4  10  100
1  5  20   50
Frappé
la source
fonctionne, mais pas si nom_colonne contient des caractères spéciaux.
jimh
oh n'y avait pas pensé
Hit
3

Forme fonctionnelle générique

def select_columns(data_frame, column_names):
    new_frame = data_frame.loc[:, column_names]
    return new_frame

Spécifique à votre problème ci-dessus

selected_columns = ['A', 'C', 'D']
new = select_columns(old, selected_columns)
Deslin Naidoo
la source
2

Si vous souhaitez avoir une nouvelle trame de données, alors:

import pandas as pd
old = pd.DataFrame({'A' : [4,5], 'B' : [10,20], 'C' : [100,50], 'D' : [-30,-50]})
new=  old[['A', 'C', 'D']]
Un mensonge
la source
1

Pour autant que je sache, vous n'avez pas nécessairement besoin de spécifier l'axe lors de l'utilisation de la fonction de filtre.

new = old.filter(['A','B','D'])

renvoie le même dataframe que

new = old.filter(['A','B','D'], axis=1)
Ellen
la source
1

colonnes par index:

# selected column index: 1, 6, 7
new = old.iloc[: , [1, 6, 7]].copy() 
voilier009
la source