Como selecionar todas as colunas, exceto uma coluna nos pandas?

279

Eu tenho um quadro de dados parecido com 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

Como posso obter todas as colunas, exceto column b?

Markov Zain
fonte
@ cs95 - O destino duplicado listado atualmente não é duplicado. Apesar do título original, a pergunta vinculada é "Por que essa sintaxe específica não funciona", enquanto essa pergunta é mais geral "Qual é a melhor maneira de fazer isso". - Adicione a isso a diferença entre excluir uma coluna de um DataFrame existente e criar um novo DataFrame com todas, exceto uma das colunas da outra.
RM
@RM Me desculpe, mas não concordo com a edição que você fez no título desse post, então revirei. É verdade que a intenção do OP era questionar a sintaxe, mas a postagem cresceu para abordar a questão mais ampla de como excluir uma coluna. As respostas neste post são cópias em carbono do post mais votado lá. O idiota fica.
cs95 21/05/19
Observe que esta questão está sendo discutida no Meta .
Heretic Monkey

Respostas:

422

Quando as colunas não são um MultiIndex, df.columnsé apenas uma matriz de nomes de colunas para que você possa fazer:

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
Marius
fonte
13
Nada mal, mas a solução de @ mike usando dropé melhor IMO. Um pouco mais legíveis e alças multiindexes
travc
5
Na verdade, eu concordo que a solução de @ mike dropé melhor - acho útil descobrir que colunas (de nível único) são matrizes com as quais você pode trabalhar, mas especificamente para soltar uma coluna, dropé muito legível e funciona bem com índices complexos.
Marius
1
Obrigado por esta ótima resposta. e se eu não tiver um cabeçalho? como eu me dirijo?
FabioSpaghetti 17/09/19
1
E quando você tem mais de uma coluna a ser ignorada?
Bruno Ambrozio 26/03
@ Marius Isso funciona com várias colunas (digamos duas)?
MasayoMusic
228

Não use ix. Está obsoleto . A maneira mais legível e idiomática de fazer isso é 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

Observe que, por padrão, .drop()não opera no local; apesar do nome ameaçador, não dfé prejudicado por esse processo. Se você deseja remover permanentemente ba partir df, faça df.drop('b', inplace=True).

df.drop()também aceita uma lista de rótulos, por exemplo df.drop(['a', 'b'], axis=1), soltará a coluna ae b.

Mike
fonte
1
Também funciona em um multi-índice como você esperaria. df.drop([('l1name', 'l2name'), 'anotherl1name'], axis=1). Parece usar lista vs tupla para determinar se você deseja várias colunas (lista) ou se referir a um multi-índice (tupla).
travc
16
Mais legível: df.drop(columns='a')ou df.drop(columns=['a', 'b']). Também pode substituir columns=com index=.
BallpointBen
No entanto, isso não é útil se você não souber os nomes de todas as colunas que deseja soltar.
Yeliabsalohcin # 4/18
Como isso cria uma cópia e não uma visão / referência, não é possível modificar o quadro de dados original usando-o no LHS de uma atribuição.
Jan Christoph Terasa
@JanChristophTerasa Você sabe como modificar essas colunas selecionadas no df original (multiplique todas essas colunas pelos valores de outra coluna). Se eu modificar esses valores, precisaria aderir à coluna solta no final, o que não parece ser o melhor caminho.
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
fonte
9
Eu gosto dessa abordagem, pois ela pode ser usada para omitir mais de uma coluna.
Nischal Hp
3
@NischalHp df.drop pode também omitir mais do que um df.drop coluna ([ 'a', 'b'], eixo = 1)
Patrick Li
2
Eu acho que é importante notar que este pode re-organizar as suas colunas
ocean800
1
@ ocean800 Sim, é verdade. Você pode passar sort=Falsese você quer evitar que o comportamento ( df.columns.difference(['b'], sort=False))
ayhan
64

Você pode usar df.columns.isin()

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

Quando você deseja soltar várias colunas, é simples:

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

Aqui está outra maneira:

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

Você apenas passa todas as colunas a serem exibidas, exceto a que você não deseja.

Salvador Dalí
fonte
5

Outra pequena modificação no @Salvador Dali permite que uma lista de colunas seja excluída:

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

ou

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

Eu acho que a melhor maneira de fazer é a maneira mencionada por @Salvador Dali. Não que os outros estejam errados.

Porque quando você tem um conjunto de dados em que deseja apenas selecionar uma coluna e colocá-la em uma variável e o restante das colunas em outra para fins de comparação ou computacionais. Soltar a coluna do conjunto de dados pode não ajudar. Obviamente, também existem casos de uso para isso.

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

Em seguida, você pode colocar a coleção de colunas na variável x_colsem outra variável, como x_cols1em outros cálculos.

ex: x_cols1 = data[x_cols]
Sudhi
fonte
Você pode explicar por que essa é uma resposta separada, em vez de um comentário / extensão da resposta de Salvador?
3

Aqui está uma lambda de uma linha:

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

depois de :

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
fonte