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.