Come selezionare tutte le colonne, tranne una colonna in Panda?


280

Ho un frame di dati simile a questo:

import pandas
import numpy as np
df = DataFrame(np.random.rand(4,4), columns = list('abcd'))
df
      a         b         c         d
0  0.418762  0.042369  0.869203  0.972314
1  0.991058  0.510228  0.594784  0.534366
2  0.407472  0.259811  0.396664  0.894202
3  0.726168  0.139531  0.324932  0.906575

Come posso ottenere tutte le colonne tranne column b?


@ cs95 - Il target duplicato attualmente elencato non è un duplicato. Nonostante il titolo originale, la domanda collegata è "Perché questa sintassi specifica non funziona", mentre questa domanda è un più generale "Qual è il modo migliore per farlo". - Aggiungete a ciò la differenza tra l'eliminazione di una colonna da un DataFrame esistente rispetto alla creazione di un nuovo DataFrame con quasi tutte le colonne di un altro.
RM

@RM Mi dispiace ma non sono d'accordo con la modifica che hai apportato al titolo su quel post, quindi l'ho ripristinato. È vero che l'intento del PO era mettere in discussione la sintassi, ma il post è cresciuto per rispondere alla domanda più ampia su come eliminare una colonna. Le risposte in questo post sono copie carbone del post più votato lì. Il dupe rimane.
cs95,

Nota che questa domanda è in discussione su Meta .
Heretic Monkey,

Risposte:


422

Quando le colonne non sono un MultiIndex, df.columnsè solo una matrice di nomi di colonne, quindi puoi fare:

df.loc[:, df.columns != 'b']

          a         c         d
0  0.561196  0.013768  0.772827
1  0.882641  0.615396  0.075381
2  0.368824  0.651378  0.397203
3  0.788730  0.568099  0.869127

13
Non male, ma la soluzione di @ mike dropè IMO migliore. Un po 'più leggibile e gestisce i multiindici
travc il

5
In realtà sono d'accordo sul fatto che la soluzione di @ mike dropsia migliore - penso sia utile scoprire che le colonne (a livello singolo) sono array con cui puoi lavorare, ma in particolare per far cadere una colonna, dropè molto leggibile e funziona bene con indici complessi.
Marius,

1
Grazie per questa risposta greate. cosa succede se non ho un'intestazione? come posso indirizzo?
FabioSpaghetti,

1
Che dire quando hai più di 1 colonna da ignorare?
Bruno Ambrozio,

@Marius Funziona con più colonne (diciamo due)?
MasayoMusic

228

Non usare ix. È deprecato . Il modo più leggibile e idiomatico di farlo è df.drop():

>>> df

          a         b         c         d
0  0.175127  0.191051  0.382122  0.869242
1  0.414376  0.300502  0.554819  0.497524
2  0.142878  0.406830  0.314240  0.093132
3  0.337368  0.851783  0.933441  0.949598

>>> df.drop('b', axis=1)

          a         c         d
0  0.175127  0.382122  0.869242
1  0.414376  0.554819  0.497524
2  0.142878  0.314240  0.093132
3  0.337368  0.933441  0.949598

Si noti che per impostazione predefinita, .drop()non funziona sul posto; nonostante il nome inquietante, dfè illeso da questo processo. Se si desidera rimuovere definitivamente bda df, fare df.drop('b', inplace=True).

df.drop()accetta anche un elenco di etichette, ad esempio df.drop(['a', 'b'], axis=1)lascerà cadere la colonna ae b.


1
Funziona anche su un multiindex proprio come ti aspetteresti. df.drop([('l1name', 'l2name'), 'anotherl1name'], axis=1). Sembra usare list vs tuple per determinare se vuoi più colonne (list) o fare riferimento a un multiindex (tuple).
travc,

16
Più leggibile: df.drop(columns='a')o df.drop(columns=['a', 'b']). Può anche sostituire columns=con index=.
BallpointBen

Tuttavia, questo non è utile se ti capita di non conoscere i nomi di tutte le colonne che vuoi rilasciare.
yeliabsalohcin

1
Dal momento che ciò crea una copia e non una vista / riferimento, non è possibile modificare il frame di dati originale utilizzandolo sull'LHS di un compito.
Jan Christoph Terasa,

@JanChristophTerasa Ti capita di sapere come modificare queste colonne selezionate all'interno di df originale (ad esempio moltiplicare tutte queste colonne con i valori di un'altra colonna). Se modifico questi valori, dovrei virare sulla colonna rilasciata alla fine, che non sembra essere il modo migliore.
MasayoMusic

132
df[df.columns.difference(['b'])]

Out: 
          a         c         d
0  0.427809  0.459807  0.333869
1  0.678031  0.668346  0.645951
2  0.996573  0.673730  0.314911
3  0.786942  0.719665  0.330833

9
Mi piace questo approccio in quanto può essere utilizzato per omettere più di una colonna.
Nischal Hp,

3
@NischalHp df.drop può anche omettere più di una colonna df.drop (['a', 'b'], axis = 1)
Patrick Li

2
Penso che valga la pena notare che questo può riorganizzare le tue colonne
ocean800

1
@ ocean800 Sì, è vero. Puoi passare sort=Falsese vuoi evitare quel comportamento ( df.columns.difference(['b'], sort=False))
ayhan

65

Puoi usare df.columns.isin()

df.loc[:, ~df.columns.isin(['b'])]

Quando vuoi eliminare più colonne, semplice come:

df.loc[:, ~df.columns.isin(['col1', 'col2'])]

12

Ecco un altro modo:

df[[i for i in list(df.columns) if i != '<your column>']]

Basta passare tutte le colonne per essere mostrate tranne quella che non si desidera.


5

Un'altra leggera modifica a @Salvador Dali consente di escludere un elenco di colonne:

df[[i for i in list(df.columns) if i not in [list_of_columns_to_exclude]]]

o

df.loc[:,[i for i in list(df.columns) if i not in [list_of_columns_to_exclude]]]

4

Penso che il modo migliore per farlo sia quello menzionato da @Salvador Dali. Non che gli altri abbiano torto.

Perché quando hai un set di dati in cui vuoi solo selezionare una colonna e metterla in una variabile e il resto delle colonne in un'altra per scopi di confronto o di calcolo. Quindi eliminare la colonna del set di dati potrebbe non essere d'aiuto. Naturalmente ci sono casi d'uso anche per quello.

x_cols = [x for x in data.columns if x != 'name of column to be excluded']

Quindi puoi mettere quella raccolta di colonne in variabile x_colsin un'altra variabile come x_cols1per altri calcoli.

ex: x_cols1 = data[x_cols]

Puoi spiegare perché questa è una risposta separata anziché un commento / estensione alla risposta di Salvador?

3

Ecco una lambda a una riga:

df[map(lambda x :x not in ['b'], list(df.columns))]

prima :

import pandas
import numpy as np
df = pd.DataFrame(np.random.rand(4,4), columns = list('abcd'))
df

       a           b           c           d
0   0.774951    0.079351    0.118437    0.735799
1   0.615547    0.203062    0.437672    0.912781
2   0.804140    0.708514    0.156943    0.104416
3   0.226051    0.641862    0.739839    0.434230

dopo :

df[map(lambda x :x not in ['b'], list(df.columns))]

        a          c          d
0   0.774951    0.118437    0.735799
1   0.615547    0.437672    0.912781
2   0.804140    0.156943    0.104416
3   0.226051    0.739839    0.434230
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.