web-dev-qa-db-fra.com

Supprimer la colonne de pandas DataFrame

Lors de la suppression d'une colonne dans un DataFrame, j'utilise:

del df['column_name']

Et ça marche très bien. Pourquoi ne puis-je pas utiliser ce qui suit?

del df.column_name

Comme vous pouvez accéder à la colonne/série en tant que df.column_name, cela devrait fonctionner.

914
John

Il est difficile de faire fonctionner del df.column_name simplement en raison de limitations syntaxiques en Python. del df[name] est traduit en df.__delitem__(name) par Python.

512
Wes McKinney

La meilleure façon de faire cela dans les pandas est d'utiliser drop :

df = df.drop('column_name', 1)

1 est le numéro axis (0 pour les lignes et 1 pour les colonnes).

Pour supprimer la colonne sans avoir à réaffecter df, vous pouvez procéder comme suit:

df.drop('column_name', axis=1, inplace=True)

Enfin, pour supprimer la colonne numéro au lieu de la colonne label, essayez de supprimer, par exemple. les 1ère, 2ème et 4ème colonnes:

df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 
1681
LondonRob

Utilisation:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)

Cela supprimera une ou plusieurs colonnes en place. Notez que inplace=True a été ajouté dans pandas v0.13 et ne fonctionnera pas avec les versions antérieures. Dans ce cas, vous devez réattribuer le résultat:

df = df.drop(columns, axis=1)
194
Krishna Sankar

Drop par index

Supprimer les première, deuxième et quatrième colonnes:

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)

Supprimer la première colonne:

df.drop(df.columns[[0]], axis=1, inplace=True)

Il existe un paramètre facultatif inplace qui permet de modifier le fichier originaldata sans créer de copie.

Sauté

Sélection, addition, suppression de colonnes

Supprimer la colonne column-name:

df.pop('column-name')

Exemples:

df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient='index', columns=['one', 'two', 'three'])

print df:

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9

df.drop(df.columns[[0]], axis=1, inplace=True)print df:

   two  three
A    2      3
B    5      6
C    8      9

three = df.pop('three')print df:

   two
A    2
B    5
C    8
90
jezrael

La question posée, manquée par la plupart des réponses, est la suivante:

Pourquoi ne puis-je pas utiliser del df.column_name?

Nous devons d’abord comprendre le problème, ce qui nous oblige à plonger dans méthodes magiques python .

Comme Wes le souligne dans sa réponse, del df['column'] correspond au python méthode magiquedf.__delitem__('column') qui est implémenté dans des pandas pour supprimer la colonne

Cependant, comme indiqué dans le lien ci-dessus à propos de méthodes magiques python :

En fait, del ne devrait presque jamais être utilisé en raison des circonstances précaires dans lesquelles il est appelé; utilisez-le avec prudence!

Vous pourriez argumenter que del df['column_name'] ne devrait pas être utilisé ou encouragé et que, par conséquent, del df.column_name ne devrait même pas être pris en compte.

Cependant, en théorie, del df.column_name pourrait être implémenté pour fonctionner dans les pandas en utilisant le méthode magique __delattr__ . Cela introduit toutefois certains problèmes, des problèmes que l'implémentation del df['column_name'] a déjà, mais dans une moindre mesure.

Exemple de problème

Que se passe-t-il si je définis une colonne dans une structure de données appelée "dtypes" ou "colonnes"?.

Puis supposons que je veux supprimer ces colonnes.

del df.dtypes rendrait la méthode __delattr__ confuse, comme si elle devait supprimer l'attribut "dtypes" ou la colonne "dtypes".

Des questions d'architecture derrière ce problème

  1. Une base de données est-elle une collection De colonnes?
  2. Une base de données est-elle une collection de lignes?
  3. Une colonne est-elle un attribut d'un cadre de données?

Les pandas répondent:

  1. Oui, à tous points de vue
  2. Non, mais si vous le souhaitez, vous pouvez utiliser les méthodes .ix, .loc ou .iloc.
  3. Voulez-vous peut-être lire données? Alors oui, sauf si le nom de l'attribut est déjà pris par un autre attribut appartenant à la trame de données. Voulez-vous modifier données? Alors non.

TLDR;

Vous ne pouvez pas faire del df.column_name car les pandas ont une architecture assez sauvage qui doit être repensée pour que ce type de dissonance cognitive ne se produise pas pour ses utilisateurs.

Protip:

N'utilisez pas df.column_name, cela peut être joli, mais cela cause dissonance cognitive

Zen of Python cite cela entre ici:

Il existe plusieurs manières de supprimer une colonne.

Il devrait y avoir une - et de préférence une seule - manière évidente de le faire.

Les colonnes sont parfois des attributs mais parfois pas.

Les cas spéciaux ne sont pas assez spéciaux pour enfreindre les règles.

del df.dtypes supprime-t-il l'attribut dtypes ou la colonne dtypes?

Face à l'ambiguïté, refusez la tentation de deviner.

57
firelynx

Un ajout intéressant est la possibilité de supprimer des colonnes uniquement si elles existent. De cette façon, vous pouvez couvrir plus de cas d'utilisation, et il ne supprimera que les colonnes existantes des étiquettes qui lui ont été transmises:

Ajoutez simplement errors = 'ignore', par exemple .:

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • Ceci est nouveau à partir de Pandas 0.16.1. La documentation est ici .
45
eiTan LaVi

à partir de la version 0.16.1 vous pouvez faire 

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
39
sushmit

Il est recommandé de toujours utiliser la notation []. Une des raisons est que la notation d'attribut (df.column_name) ne fonctionne pas pour les index numérotés:

In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])

In [2]: df[1]
Out[2]:
0    2
1    5
Name: 1

In [3]: df.1
  File "<ipython-input-3-e4803c0d1066>", line 1
    df.1
       ^
SyntaxError: invalid syntax
26
Andy Hayden

Dans les pandas 0.16.1+, vous pouvez supprimer des colonnes uniquement si elles existent conformément à la solution publiée par @eiTanLaVi. Avant cette version, vous pouvez obtenir le même résultat via une compréhension de liste conditionnelle:

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)
20
Alexander

Pandas 0.21+ réponse

La version 0.21 de Pandas a légèrement modifié la méthode drop pour inclure à la fois les paramètres index et columns afin qu'ils correspondent à la signature des méthodes rename et reindex

df.drop(columns=['column_a', 'column_c'])

Personnellement, je préfère utiliser le paramètre axis pour désigner les colonnes ou l’index, car c’est le paramètre de mot clé prédominant utilisé dans presque toutes les méthodes pandas. Mais maintenant, vous avez quelques choix ajoutés dans la version 0.21.

15
Ted Petrou

Si vous souhaitez supprimer une seule colonne (col_name) d'une image (df), essayez l'une des opérations suivantes:

df = df.drop(col_name, axis=1)

OU 

df.drop(col_name, axis=1, inplace=True)

Si vous souhaitez supprimer une liste de colonnes (col_lst = [col_name_1,col_name_2,...]) à partir d'une image (df), essayez l'une des opérations suivantes:

df.drop(col_lst, axis=1, inplace=True)

OU 

df.drop(columns=col_lst, inplace=True)
7
Stephanie

La syntaxe à points fonctionne en JavaScript, mais pas en Python.

  • Python: del df['column_name']
  • JavaScript: del df['column_name'] ou del df.column_name
2
Doctor

Supprimer des colonnes de plusieurs cadres de données

Si vous êtes venu ici pour rechercher des informations sur la manière de supprimer une colonne (ayant le même nom) d'une liste de DataFrames, il existe plusieurs façons de le faire.

Une méthode consiste à parcourir la liste et à modifier chaque DataFrame sur place:

# In-place assignment
for df in df_list:
    df.drop('colname', axis=1, inplace=True)

Ou,

for df in df_list: df.pop('colname')

Sinon, supprimez la colonne (pas sur place) et associez le résultat à cette position dans la liste.

# Reassigning a copy back to the list
for i, df in enumerate(df_list):
    df_list[i] = df.drop('colname', axis=1, inplace=True)

Exemple de code reproductible

df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [4, 5, 7], 'C': ['a', 'b', 'c']})

df1
   A  B
0  1  4
1  2  5
2  3  6

df2
   A  C
0  4  a
1  5  b
2  7  c

df_list = [df1, df2]
# Drop column "A"
for df in df_list:
    df.drop('A', axis=1, inplace=True)

df1
   B
0  4
1  5
2  6

df2
   C
0  a
1  b
2  c

Pourquoi for df in df_list: df = df.drop('colname', axis=1) (c'est-à-dire, la réaffectation à l'intérieur de la boucle) ne fonctionne-t-il pas?

Comme mentionné dans d'autres réponses, df.drop renvoie une copie par défaut. La copie est renvoyée et réaffectée à la variabledf, sans aucune modification de l'original. Vous devrez soit modifier df sur place avec l'argument inplace=True, soit réaffecter explicitement la copie à cet élément de la liste.

Note
Il est important de comprendre la différence entre les variables et les objets. Les variables contiennent des références à des objets. Les variables peuvent être réaffectées pour référencer différents objets, cela n'a rien à voir avec la modification de l'objet lui-même. Pour une bonne introduction à ce sujet, je recommande de lire cet article de Ned Batchelder.

1
cs95

Une autre façon de supprimer une colonne dans Pandas DataFrame

si vous ne recherchez pas la suppression sur place, vous pouvez créer un nouveau DataFrame en spécifiant les colonnes en utilisant la fonction DataFrame(...)

my_dict = { 'name' : ['a','b','c','d'], 'age' : [10,20,25,22], 'designation' : ['CEO', 'VP', 'MD', 'CEO']}

df = pd.DataFrame(my_dict)

Créez un nouveau DataFrame en tant que

newdf = pd.DataFrame(df, columns=['name', 'age'])

Vous obtenez un résultat aussi bon que ce que vous obtenez avec del/drop

0
Daksh