Как выбрать все столбцы, кроме одного столбца в пандах?

280

У меня датафрейм выглядит так:

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

Как я могу получить все столбцы, кроме column b?

Марков Заин
источник
@ cs95 - указанная в данный момент двойная цель не является дубликатом. Несмотря на оригинальное название, связанный вопрос звучит так: «Почему не работает этот специфический синтаксис», тогда как этот вопрос носит более общий характер: «Как лучше всего это сделать». - Добавьте к этому разницу между удалением столбца из существующего DataFrame и созданием нового DataFrame со столбцами другого, кроме одного.
RM
@ ПМ, извините, но я не согласен с тем, что вы изменили заголовок этого поста, поэтому я откатился назад. Это правда, что целью OP было поставить под сомнение синтаксис, но пост вырос до более широкого вопроса о том, как удалить столбец. Ответы в этом посте - точные копии самых высоких постов там. Дупе остается.
cs95
Обратите внимание, что этот вопрос обсуждается в Meta .
Еретик Обезьяна

Ответы:

422

Когда столбцы не являются MultiIndex, df.columnsэто просто массив имен столбцов, так что вы можете сделать:

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
источник
13
Неплохо, но решение @ mike dropлучше использовать IMO. Чуть более
читабелен
5
Я на самом деле согласен с тем, что использование решения @ mike dropлучше - я думаю, что полезно выяснить, что (одноуровневые) столбцы - это массивы, с которыми вы можете работать, но, в частности, для удаления столбцов, они dropочень удобочитаемы и хорошо работают со сложными индексами.
Мариус
1
Спасибо за этот отличный ответ. что если у меня нет заголовка? как мне обратиться?
ФабиоСпагетти
1
Как насчет того, когда вам нужно игнорировать более 1 столбца?
Бруно Амброзио
@Marius Это работает с несколькими столбцами (скажем, два)?
MasayoMusic
228

Не используйте ix. Это устарело . Наиболее читаемый и идиоматический способ сделать это 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

Обратите внимание, что по умолчанию .drop()не работает на месте; несмотря на зловещее имя, dfэтот процесс не пострадал. Если вы хотите навсегда удалить bиз df, сделайте df.drop('b', inplace=True).

df.drop()также принимает список меток, например df.drop(['a', 'b'], axis=1), удалит столбец aи b.

Майк
источник
1
Также работает на мультииндекс, как вы и ожидали. df.drop([('l1name', 'l2name'), 'anotherl1name'], axis=1), Кажется, использует список против кортежа, чтобы определить, хотите ли вы иметь несколько столбцов (список) или ссылаться на мультииндекс (кортеж).
travc
16
Более читабельно: df.drop(columns='a')или df.drop(columns=['a', 'b']). Можно также заменить columns=на index=.
BallpointBen
Однако это бесполезно, если вы не знаете имен всех столбцов, которые хотите отбросить.
Йелиабсалоцин
1
Так как это создает копию, а не представление / ссылку, вы не можете изменить исходный кадр данных, используя это в LHS назначения.
Ян Кристоф Тераза
@JanChristophTerasa Вы знаете, как изменить эти выбранные столбцы в исходном df (например, умножьте все эти столбцы на значения другого столбца). Если я изменю эти значения, мне нужно будет добавить упавший столбец в конец, что не кажется лучшим способом.
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
Мне нравится этот подход, так как он может быть использован, чтобы опустить более одного столбца.
Nischal Hp
3
@NischalHp df.drop также может опускать более одного столбца df.drop (['a', 'b'], axis = 1)
Патрик Ли
2
Я думаю, что стоит отметить, что это может переставить ваши колонки
ocean800
1
@ ocean800 Да, это правда. Вы можете пройти , sort=Falseесли вы хотите , чтобы избежать такого поведения ( df.columns.difference(['b'], sort=False))
Айхан
65

Ты можешь использовать df.columns.isin()

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

Если вы хотите удалить несколько столбцов, просто:

df.loc[:, ~df.columns.isin(['col1', 'col2'])]
Том
источник
12

Вот еще один способ:

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

Вы просто передаете все отображаемые столбцы, кроме одного, который вам не нужен.

Сальвадор Дали
источник
5

Еще одно небольшое изменение в @Salvador Dali позволяет исключить список столбцов:

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

или

df.loc[:,[i for i in list(df.columns) if i not in [list_of_columns_to_exclude]]]
user1718097
источник
4

Я думаю, что лучший способ сделать это - путь, упомянутый Сальвадором Дали. Не то чтобы другие не правы.

Потому что, когда у вас есть набор данных, в котором вы просто хотите выбрать один столбец и поместить его в одну переменную, а остальные столбцы - в другую для сравнения или в вычислительных целях. Тогда удаление столбца набора данных может не помочь. Конечно, для этого есть варианты использования.

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

Затем вы можете поместить эти коллекции столбцов в переменную x_colsв другую переменную, как x_cols1для других вычислений.

ex: x_cols1 = data[x_cols]
Sudhi
источник
Можете ли вы объяснить, почему это отдельный ответ, а не комментарий / расширение ответа Сальвадора?
3

Вот одна строка лямбда:

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

до :

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

после :

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
Грант Шеннон
источник