如何在pandas中选择除一个之外的所有列?

557
我有一个看起来像这样的数据框:
          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

如何获取除了b之外的所有列?

@cs95 -- 目前列出的重复目标并不是重复的。尽管原标题如此,但链接的问题是“为什么这个特定的语法不起作用”,而这个问题是一个更一般的“做这件事的最佳方法是什么”。-- 另外还有从现有DataFrame中删除列与创建一个新的DataFrame,其中包含另一个DataFrame的除一个列之外的所有列之间的区别。 - R.M.
@R.M. 很抱歉,我不同意你对那篇帖子标题所做的编辑,因此我已经将其回滚。虽然OP的意图是质疑语法,但这篇文章已经发展成为解决如何删除列的更广泛问题。这篇文章中的答案与最受欢迎的帖子中的答案完全相同。重复内容保留。 - cs95
请注意,此问题正在Meta上讨论。 - Heretic Monkey
14个回答

770
当列不是 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

31
还不错,但我个人认为@mike使用drop的解决方案更好。这种方法更易读,并且可以处理多级索引。 - travc
7
我同意 @mike 使用 drop 的解决方案更好 - 我认为发现(单层)列是可以使用的数组很有用,但是特别是对于删除列来说,drop 很易读,而且在处理复杂索引时也能很好地工作。 - Marius
1
谢谢您提供这个很棒的答案。如果我没有标题,该如何处理?我该怎么解决? - FabioSpaghetti
3
当您有多于1列需要忽略时该怎么办? - Bruno Ambrozio
1
@Marius 这个适用于多列(比如两列)吗? - MasayoMusic
试用的方法是 df.loc[:, (df.columns != 'b') & (df.columns != 'c')]然而,这种方法增长得太快了。我们也可以这样做from functools import reduce df.loc[:, reduce(lambda x, y: x & (df.columns != y), ["b", "c"], df.columns != "z")]并添加我们喜欢的列(假设我们没有列“z”)。但是,在这一点上,最好使用.drop() - an_drade

425
不要使用ix。它已经被弃用了。最易读和惯用的方法是使用df.drop()
>>> df.drop('b', axis=1)
          a         c         d
0  0.418762  0.869203  0.972314
1  0.991058  0.594784  0.534366
2  0.407472  0.396664  0.894202
3  0.726168  0.324932  0.906575

请注意,默认情况下,.drop() 不会在原地操作;尽管名字听起来很可怕,但这个过程不会对 df 造成任何伤害。如果你想永久删除 df 中的 b,可以使用 df.drop('b', inplace=True)df.drop() 还接受一个标签列表作为参数,例如 df.drop(['a', 'b'], axis=1) 将删除列 ab

2
也可以像预期的那样在多级索引上工作。df.drop([('l1name','l2name'),'anotherl1name'],axis = 1)。似乎使用列表与元组来确定您是否需要多个列(列表)或引用多级索引(元组)。 - travc
63
更易读的写法是 df.drop('a', axis=1) 或者 df.drop(['a', 'b'], axis=1),也可以使用 axis=0 来代替 axis=1,实现删除行操作。 - BallpointBen
然而,如果您恰好不知道要删除的所有列的名称,则此方法并不实用。 - yeliabsalohcin
5
由于这样会创建一个副本而不是视图/引用,因此您不能使用此方法在赋值语句的左侧修改原始数据框。 - Jan Christoph Terasa
我同意“最易读和惯用的方法是使用df.drop()”!简单易懂。 - mapperx
显示剩余2条评论

221
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

16
我喜欢这种方法,因为它可以用于省略超过一个列。 - Nischal Hp
3
@NischalHp df.drop()函数也可以删除多列,例如df.drop(['a', 'b'], axis=1)。 - JACKY88
5
值得注意的是,这可能会重新排列您的列。 - ocean800
5
是的,如果您想避免这种行为,可以传递 sort=Falsedf.columns.difference(['b'], sort=False))。 - ayhan
这是在DataFrameGroupBy上运行的最佳方法,这正是我正在寻找的,谢谢!我使用了grouped[df.columns.difference(['b'])]... - wjandrea
这种方法很好,因为它可以与多个列一起使用,并且可以在 loc 内部使用,例如,如果您想要更新除 2 之外的所有列。此外,它非常易于使用,语法清晰明了。 - Haeden

146
你可以使用 df.columns.isin()
df.loc[:, ~df.columns.isin(['b'])]

当您想删除多列时,只需简单地执行以下操作:

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

这种方法对于修改所选列非常有帮助! - Derek O

38
你可以在索引中删除列:
df[df.columns.drop('b')]

或者

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

如果你需要删除多列,使用一个标签列表而不是一个单独的标签。

15

这里有另一种方式:

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

您只需传递要显示的所有列,除了您不想要的那一列。


9

以下是一行Lambda表达式:

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

after:

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

7

我认为最好的方法是@Salvador Dali提到的方法。并不是其他方法是错误的。

因为当你有一个数据集,只想选择一列并将其放入一个变量中,而将其他列放入另一个变量中进行比较或计算时,删除数据集的列可能没有帮助。当然也有使用情况。

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]

你能解释一下为什么这是一个单独的答案,而不是对Salvador的回答进行评论/扩展吗? - user6839822

7

对@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]]]

3
与@Toms的答案类似,也可以在不使用.loc的情况下选择除“b”以外的所有列,方法如下:
df[df.columns[~df.columns.isin(['b'])]]

为什么要使用.loc或者简单的方括号? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接