¿Cómo seleccionar todas las columnas, excepto una columna en pandas?

280

Tengo un marco de datos como este:

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

¿Cómo puedo obtener todas las columnas excepto column b?

markov zain
fuente
@ cs95: el objetivo duplicado actualmente listado no es un duplicado. A pesar del título original, la pregunta vinculada es "¿Por qué no funciona esta sintaxis específica?", Mientras que esta pregunta es más general "¿Cuál es la mejor manera de hacer esto?". - Agregue a esto la diferencia entre eliminar una columna de un DataFrame existente versus crear un nuevo DataFrame con todas las columnas menos una.
RM
@RM Lo siento, pero no estoy de acuerdo con la edición que hiciste en el título de esa publicación, así que lo revertí. Es cierto que la intención del OP era cuestionar la sintaxis, pero la publicación ha crecido para abordar la pregunta más amplia de cómo eliminar una columna. Las respuestas en esta publicación son copias al carbón de la publicación más votada allí. El engañado se queda.
cs95
Tenga en cuenta que esta pregunta se está discutiendo en Meta .
Heretic Monkey

Respuestas:

422

Cuando las columnas no son un MultiIndex, df.columnses solo una matriz de nombres de columnas para que pueda hacer:

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
Mario
fuente
13
No está mal, pero la solución de @ mike usando dropes mejor IMO. Un poco más legible y maneja
múltiples índices
55
De hecho, estoy de acuerdo en que el uso de la solución @ mike dropes mejor; creo que es útil descubrir que las columnas (de un solo nivel) son matrices con las que puede trabajar, pero específicamente para soltar una columna, dropes muy legible y funciona bien con índices complejos.
Marius
1
Gracias por esta gran respuesta. ¿Qué pasa si no tengo un encabezado? ¿Cómo me dirijo?
FabioSpaghetti
1
¿Qué pasa cuando tienes que ignorar más de 1 columna?
Bruno Ambrozio
@ Mario ¿Funciona esto con varias columnas (digamos dos)?
MasayoMusic
228

No utilice ix. Está en desuso . La forma más legible e idiomática de hacer esto es 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

Tenga en cuenta que, de manera predeterminada, .drop()no funciona en el lugar; a pesar del nombre ominoso, no dfsufre daños por este proceso. Si desea eliminar de forma permanente ba partir df, hacer df.drop('b', inplace=True).

df.drop()también acepta una lista de etiquetas, por ejemplo df.drop(['a', 'b'], axis=1), soltará la columna ay b.

Miguel
fuente
1
También funciona en un índice múltiple como es de esperar. df.drop([('l1name', 'l2name'), 'anotherl1name'], axis=1). Parece utilizar list vs tuple para determinar si desea varias columnas (list) o hacer referencia a un índice múltiple (tuple).
travc
16
Más legible: df.drop(columns='a')o df.drop(columns=['a', 'b']). También se puede reemplazar columns=con index=.
BallpointBen
Sin embargo, esto no es útil si no conoce los nombres de todas las columnas que desea soltar.
yeliabsalohcin
1
Como esto crea una copia y no una vista / referencia, no puede modificar el marco de datos original al usar esto en el LHS de una asignación.
Jan Christoph Terasa
@ JanChristophTerasa ¿Sabes cómo modificar estas columnas seleccionadas dentro de df original (multiplicar todas estas columnas con valores de otra columna). Si modifico estos valores, necesitaría agregar la columna caída al final, que no parece ser la mejor manera.
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
ayhan
fuente
9
Me gusta este enfoque, ya que puede usarse para omitir más de una columna.
Nischal Hp
3
@NischalHp df.drop también puede omitir más de una columna df.drop (['a', 'b'], axis = 1)
Patrick Li
2
Creo que vale la pena señalar que este puede volver a organizar sus columnas
ocean800
1
@ ocean800 Sí, eso es cierto. Puede aprobar sort=Falsesi desea evitar ese comportamiento ( df.columns.difference(['b'], sort=False))
ayhan
65

Puedes usar df.columns.isin()

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

Cuando desee soltar varias columnas, tan simple como:

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

Aquí hay otra manera:

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

Simplemente pasa todas las columnas para que se muestren, excepto la que no deseas.

Salvador Dalí
fuente
5

Otra pequeña modificación a @Salvador Dali permite excluir una lista de columnas:

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]]]
usuario1718097
fuente
4

Creo que la mejor manera de hacerlo es la mencionada por @Salvador Dali. No es que los otros estén equivocados.

Porque cuando tiene un conjunto de datos en el que solo desea seleccionar una columna y colocarla en una variable y el resto de las columnas en otra para fines de comparación o computacionales. Luego, dejar caer la columna del conjunto de datos podría no ayudar. Por supuesto, también hay casos de uso para eso.

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

Luego puede poner esa colección de columnas en variable x_colsen otra variable como x_cols1para otro cálculo.

ex: x_cols1 = data[x_cols]
Sudhi
fuente
¿Puede explicar por qué esta es una respuesta separada en lugar de un comentario / extensión de la respuesta de Salvador?
3

Aquí hay una línea lambda:

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

antes :

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

despues :

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
Grant Shannon
fuente