在删除DataFrame中的列时,我使用:

del df['column_name']


,这很好用。为什么不能使用以下内容?

del df.column_name


由于可以以df.column_name的形式访问列/系列,所以我希望它能正常工作。

评论

请注意,正在Meta上讨论此问题。

这需要再投票一次

#1 楼

如您所料,正确的语法是

del df['column_name']


仅仅由于Python的语法限制,很难使del df.column_name正常工作。通过Python将del df[name]转换为df.__delitem__(name)

评论


我意识到这是一个非常古老的“答案”,但是我的好奇心激起了-为什么这是Python的语法限制? A类(对象):def __init __(self):self.var = 1设置一个类,然后a = A(); del a.var工作得很好...

–dwanderson
16-10-4在14:24

@dwanderson的区别在于,当要删除列时,DataFrame需要具有自己的“如何执行”处理。对于del df [name],它将转换为df .__ delitem __(name),这是DataFrame可以实现并修改其需求的方法。对于del df.name,成员变量将被删除,而没有任何自定义代码运行的机会。考虑您自己的示例-是否可以获取del a.var来显示“删除变量”?如果可以的话,请告诉我如何。我不能:)

– Yonatan
16/12/22在8:27

@Yonatan您可以使用docs.python.org/3/reference/datamodel.html#object.__delattr__或描述符:docs.python.org/3/howto/descriptor.html

– Eugene Pakhomov
17年1月19日在16:06

@Yonatan Eugene的评论也适用于Python 2;描述符自2.2起就在Python 2中使用,满足您的要求很简单;)

– C S
17年6月20日在12:38

这个答案不是很正确-熊猫开发者没有,但这并不意味着很难做到。

– wizzwizz4
17年9月30日在9:42

#2 楼

在pandas中执行此操作的最佳方法是使用drop
df = df.drop('column_name', 1)

1 是轴号(0 用于行,1 用于列。)
删除列而不必重新分配df您可以执行以下操作:
df.drop('column_name', axis=1, inplace=True)

最后,要删除列号而不是列标签,请尝试删除它,例如第1列,第2列和第4列:
df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 

还对列使用“文本”语法:
df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)

注意:v0.21.0中引入(2017年10月27日) ,drop()方法可以接受index / columns关键字来替代指定轴。
因此,我们现在可以执行以下操作:
df.drop(columns=['B', 'C'])

评论


是否出于某些原因推荐使用del?

– beardc
2013年12月10日20:13在

尽管这种删除方法有其优点,但该答案并不能真正回答所提出的问题。

– Paul
2014年5月28日12:59

正确@Paul,但是由于问题的标题,大多数到达此地的人都将通过尝试找出如何删除列的方式来这样做。

–LondonRob
2014年5月28日下午16:43

@beardc drop over del的另一个优点是drop允许您一次删除多列,是否执行就地操作,也可以沿任何轴删除记录(对于3-D矩阵或Panel尤其有用)

–滚刀
16年4月14日在20:17

drop over del的另一个优点是drop是pandas API的一部分并包含文档。

–模数
16年8月12日在8:53

#3 楼

使用:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)


这将就地删除一个或多个列。请注意,inplace=True已在pandas v0.13中添加,不适用于旧版本。在这种情况下,您必须将结果分配回去:

df = df.drop(columns, axis=1)


评论


关于此答案的注释:如果使用“列表”,则应删除方括号:df.drop(list,inplace = True,axis = 1)

– edesz
17年6月14日在23:31

这确实应该是一个可以接受的答案,因为它清楚表明了此方法相对于del的优势-可以一次删除多个列。

– dbliss
17年7月4日在21:27

我相信如果您使用列kwarg,例如df.drop(columns = ['A','B']),则无需指定axis = 1。

–威廉姆斯
7月24日15:53

后来者还会在下面查看@ eiTanLaVi.solution以获得适用于熊猫0.16.1+的人,他们建议添加错误='忽略'

– micstr
9月10日9:34

#4 楼

按索引删除

删除第一,第二和第四列:

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)


删除第一列:

df.drop(df.columns[[0]], axis=1, inplace=True)


有一个可选参数inplace,以便可以在不创建副本的情况下修改原始的
数据。

已填充

列选择,添加,删除

删除列column-name

df.pop('column-name')


示例:

df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient='index', columns=['one', 'two', 'three'])


> print df

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9


df.drop(df.columns[[0]], axis=1, inplace=True)
print df

   two  three
A    2      3
B    5      6
C    8      9


three = df.pop('three')
print df

   two
A    2
B    5
C    8


评论


如何在熊猫中弹出行?

– Kennet Celeste
17年2月9日在16:10

@Yugi您可以为此使用转置数据帧。例如-df.T.pop('A')

–时钟从站
17年3月18日在11:21



@ClockSlave不会修改原始df。你可以做df = df.T; df.pop(index); df = df.T,但这似乎过多。

–cs95
19年5月23日在17:28



代替df.drop(df.columns [[0]],axis = 1,inplace = True)使用df.drop([0],axis = 1)还不够吗?

– Anirban Mukherjee
19/12/4在20:02

@Anirban Mukherjee这取决于。如果要删除列名0,则df.drop(0,axis = 1)运行良好。但是,如果不知道列名并且需要删除第一列,则需要df.drop(df.columns [[0]],axis = 1,inplace = True),它会按位置选择第一列并将其删除。

– Jezrael
19/12/4在20:42

#5 楼

在这里,大多数答案都遗漏了一个实际的问题:
我为什么不能使用del df.column_name
首先,我们需要了解这个问题,这需要我们深入研究python魔术方法。
正如Wes在他的回答中指出的那样,del df['column']映射到python魔术方法df.__delitem__('column'),该方法在熊猫中实现以删除列。
但是,如上面有关python魔术方法的链接所指出的那样:

实际上,由于被称为__del__的危险环境,几乎不应该使用它;

请谨慎使用它!您可能会说不应该使用或鼓励使用del df['column_name'],因此甚至不应该考虑使用del df.column_name
但是,从理论上讲,del df.column_name可以用于熊猫使用魔术方法__delattr__。但是,这确实引入了某些问题,即del df['column_name']实现已存在的问题,但程度较小。
示例问题
如果我在称为“ dtypes”或“ columns”的数据框中定义列,该怎么办? />然后假设我要删除这些列。
del df.dtypes会使__delattr__方法感到困惑,好像它应该删除“ dtypes”属性或“ dtypes”列一样。
此问题背后的体系结构问题

数据帧是
列的集合吗?
数据帧是行的集合吗?
列是数据帧的属性吗?

Pandas答案:

是的,在所有方面
否,但是如果您愿意,可以使用.ix.loc.iloc方法。
也许您呢想读取数据?然后是,除非该属性的名称已被属于该数据帧的另一个属性采用。您要修改数据吗?那么不能。

TLDR;
不能做del df.column_name,因为熊猫的结构非常狂野,需要重新考虑,以免使用者出现这种认知失调。 br />提示:
请勿使用df.column_name,它可能很漂亮,但会引起认知不协调。
适用于此处的Python引号的含义:
有多种删除列的方法。

应该有一种-最好只有一种-显而易见的方法。

列有时是属性,但有时不是。

特殊情况并不特殊

del df.dtypes是否删除dtypes属性或dtypes列?

模棱两可,拒绝诱惑。


评论


“实际上,由于调用__del__的情况不稳定,几乎不应该使用它;请谨慎使用!”与此处完全无关,因为此处使用的方法是__delattr__。

–pppery
18-2-22在19:27

@ppperry您错过了报价。这是del内置的意思,而不是.__ del__实例方法。我内置的del内置映射到__delattr__和__delitem__。因此,也许您想重新阅读我写的内容。

– firelynx
18年2月23日在10:01

__ ... __被StackExchange解释为粗体标记

–pppery
18年2月25日在20:20

“不要使用df.column_name,它可能很漂亮,但是会导致认知失调”。这是什么意思?我不是心理学家,所以我必须仔细检查才能理解您的意思。另外,引用《禅宗》是没有意义的,因为有数百种有效的方法可以在熊猫中做同样的事情。

–cs95
19年5月23日在17:26



#6 楼

一个不错的附加功能是仅在存在列的情况下才删除列的功能。这样,您可以涵盖更多用例,并且只会从传递给它的标签中删除现有列:

只需添加errors ='ignore'。例如::

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')



这是从熊猫0.16.1开始的新功能。文档在这里。


#7 楼

从版本0.16.1开始,您可以

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')


评论


而且这还支持删除多个列,其中一些不需要存在(即,不引发错误error ='ignore')df.drop([''column_1','column_2'],axis = 1,inplace = True,errors ='忽略”),如果需要这样的应用程序!

–μon
16-10-21在19:57



#8 楼

始终使用[]表示法是一个好习惯。原因之一是属性符号(df.column_name)对于编号索引不起作用:

In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])

In [2]: df[1]
Out[2]:
0    2
1    5
Name: 1

In [3]: df.1
  File "<ipython-input-3-e4803c0d1066>", line 1
    df.1
       ^
SyntaxError: invalid syntax


#9 楼

Pandas 0.21+答案

Pandas 0.21版对drop方法进行了少许更改,以同时包含indexcolumns参数,以匹配renamereindex方法的签名。我个人更喜欢使用axis参数来表示列或索引,因为它是几乎所有熊猫方法中都使用的主要关键字参数。但是,现在您在0.21版中有了一些其他选择。

评论


df.drop([['column_a','column_c'],axis = 1)|现在对我有用

–YouAreAwesome
18年4月22日在5:03

#10 楼

在熊猫0.16.1+中,只有根据@eiTanLaVi发布的解决方案存在的情况下,才能删除列。在该版本之前,您可以通过条件列表理解来获得相同的结果:

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)


#11 楼

TL; DR

付出了很多努力才能找到效率更高的解决方案。难以证明增加的复杂性,同时又牺牲了df.drop(dlst, 1, errors='ignore')的简单性。在语义上,删除一列与选择其他列是相同的。我将展示一些其他方法可供考虑。

我还将关注一下一次删除多个列并允许尝试删除不存在的列的一般解决方案。

使用这些解决方案是通用的,也适用于简单的情况。


设置
考虑pd.DataFrame df并列出要删除的dlst

df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)



df = pd.DataFrame(dict(zip('ABCDEFGHIJ', range(1, 11))), range(3))
dlst = list('HIJKLM')



df

   A  B  C  D  E  F  G  H  I   J
0  1  2  3  4  5  6  7  8  9  10
1  1  2  3  4  5  6  7  8  9  10
2  1  2  3  4  5  6  7  8  9  10


结果应如下所示:

dlst

['H', 'I', 'J', 'K', 'L', 'M']



由于我将删除列等同于选择其他列,因此将其分为两种类型:


标签选择
布尔选择


标签选择

我们首先制造代表所需列的标签列表/数组保留并且没有我们要删除的列。



df.columns.difference(dlst)

df.drop(dlst, 1, errors='ignore')

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7



np.setdiff1d(df.columns.values, dlst)

Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')



df.columns.drop(dlst, errors='ignore')

array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)



list(set(df.columns.values.tolist()).difference(dlst))

Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')



[x for x in df.columns.values.tolist() if x not in dlst]

# does not preserve order
['E', 'D', 'B', 'F', 'G', 'A', 'C']





标签中的列
为了比较选择过程,假设:

['A', 'B', 'C', 'D', 'E', 'F', 'G']

然后我们可以评估


df.loc[:, cols]
df[cols]
df.reindex(columns=cols)
df.reindex_axis(cols, 1)

全部求值为:

 cols = [x for x in df.columns.values.tolist() if x not in dlst]



布尔切片

我们可以构建用于切片的布尔数组/列表


~df.columns.isin(dlst)
~np.in1d(df.columns.values, dlst)
[x not in dlst for x in df.columns.values.tolist()]
(df.columns.values[:, None] != dlst).all(1)

布尔值中的列
为了比较

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7



df.loc[: bools]

谁都评价为:

bools = [x not in dlst for x in df.columns.values.tolist()]



稳健计时

功能

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7


测试

setdiff1d = lambda df, dlst: np.setdiff1d(df.columns.values, dlst)
difference = lambda df, dlst: df.columns.difference(dlst)
columndrop = lambda df, dlst: df.columns.drop(dlst, errors='ignore')
setdifflst = lambda df, dlst: list(set(df.columns.values.tolist()).difference(dlst))
comprehension = lambda df, dlst: [x for x in df.columns.values.tolist() if x not in dlst]

loc = lambda df, cols: df.loc[:, cols]
slc = lambda df, cols: df[cols]
ridx = lambda df, cols: df.reindex(columns=cols)
ridxa = lambda df, cols: df.reindex_axis(cols, 1)

isin = lambda df, dlst: ~df.columns.isin(dlst)
in1d = lambda df, dlst: ~np.in1d(df.columns.values, dlst)
comp = lambda df, dlst: [x not in dlst for x in df.columns.values.tolist()]
brod = lambda df, dlst: (df.columns.values[:, None] != dlst).all(1)



res1 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc slc ridx ridxa'.split(),
        'setdiff1d difference columndrop setdifflst comprehension'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res2 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc'.split(),
        'isin in1d comp brod'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res = res1.append(res2).sort_index()

dres = pd.Series(index=res.columns, name='drop')

for j in res.columns:
    dlst = list(range(j))
    cols = list(range(j // 2, j + j // 2))
    d = pd.DataFrame(1, range(10), cols)
    dres.at[j] = timeit('d.drop(dlst, 1, errors="ignore")', 'from __main__ import d, dlst', number=100)
    for s, l in res.index:
        stmt = '{}(d, {}(d, dlst))'.format(s, l)
        setp = 'from __main__ import d, dlst, {}, {}'.format(s, l)
        res.at[(s, l), j] = timeit(stmt, setp, number=100)

rs = res / dres



rs

                          10        30        100       300        1000
Select Label                                                           
loc    brod           0.747373  0.861979  0.891144  1.284235   3.872157
       columndrop     1.193983  1.292843  1.396841  1.484429   1.335733
       comp           0.802036  0.732326  1.149397  3.473283  25.565922
       comprehension  1.463503  1.568395  1.866441  4.421639  26.552276
       difference     1.413010  1.460863  1.587594  1.568571   1.569735
       in1d           0.818502  0.844374  0.994093  1.042360   1.076255
       isin           1.008874  0.879706  1.021712  1.001119   0.964327
       setdiff1d      1.352828  1.274061  1.483380  1.459986   1.466575
       setdifflst     1.233332  1.444521  1.714199  1.797241   1.876425
ridx   columndrop     0.903013  0.832814  0.949234  0.976366   0.982888
       comprehension  0.777445  0.827151  1.108028  3.473164  25.528879
       difference     1.086859  1.081396  1.293132  1.173044   1.237613
       setdiff1d      0.946009  0.873169  0.900185  0.908194   1.036124
       setdifflst     0.732964  0.823218  0.819748  0.990315   1.050910
ridxa  columndrop     0.835254  0.774701  0.907105  0.908006   0.932754
       comprehension  0.697749  0.762556  1.215225  3.510226  25.041832
       difference     1.055099  1.010208  1.122005  1.119575   1.383065
       setdiff1d      0.760716  0.725386  0.849949  0.879425   0.946460
       setdifflst     0.710008  0.668108  0.778060  0.871766   0.939537
slc    columndrop     1.268191  1.521264  2.646687  1.919423   1.981091
       comprehension  0.856893  0.870365  1.290730  3.564219  26.208937
       difference     1.470095  1.747211  2.886581  2.254690   2.050536
       setdiff1d      1.098427  1.133476  1.466029  2.045965   3.123452
       setdifflst     0.833700  0.846652  1.013061  1.110352   1.287831


这与运行df.drop(dlst, 1, errors='ignore')所需的时间有关。似乎经过所有这些努力,我们只能适度地提高性能。



如果实际上最好的解决方案在reindex上使用reindex_axislist(set(df.columns.values.tolist()).difference(dlst))drop紧随其后,但仍比np.setdiff1d好一点。

fig, axes = plt.subplots(2, 2, figsize=(8, 6), sharey=True)
for i, (n, g) in enumerate([(n, g.xs(n)) for n, g in rs.groupby('Select')]):
    ax = axes[i // 2, i % 2]
    g.plot.bar(ax=ax, title=n)
    ax.legend_.remove()
fig.tight_layout()


#12 楼

我们可以通过drop()方法删除或删除指定的列或特定的列。

假设df是一个数据帧。

要删除的列= column0


代码:


df = df.drop(column0, axis=1)


到删除多列col1,col2 、. 。 。 ,coln,我们必须在列表中插入所有需要删除的列。然后通过drop()方法将其删除。


代码:


df = df.drop([col1, col2, . . . , coln], axis=1)


我希望这会有所帮助。

评论


df = df.drop([col1,col2,。。。,coln],axis = 1)如果我指定变量名代替col1,col2等,则此方法不起作用。当下。 @Littin你能帮忙吗?

– RSM
5月20日5:54

#13 楼

df.drop('columnname', axis =1, inplace = True)

,或者您可以选择
del df['colname']

根据列号删除多列
df.drop(df.iloc[:,1:3], axis = 1, inplace = True)

根据列名删除多列
df.drop(['col1','col2',..'coln'], axis = 1, inplace = True)


#14 楼

如果原始数据帧df不太大,则没有内存限制,您只需要保留几列,或者,如果您事先不知道不需要的所有额外列的名称,那么您可以可能只用您需要的列创建一个新的数据框:
new_df = df[['spam', 'sausage']]


#15 楼

点语法在JavaScript中有效,但在Python中无效。


Python:del df['column_name']

JavaScript:del df['column_name']del df.column_name



#16 楼

另一种删除Pandas DataFrame中的列的方法

如果您不希望就地删除,则可以通过使用DataFrame(...)函数将这些列指定为

my_dict = { 'name' : ['a','b','c','d'], 'age' : [10,20,25,22], 'designation' : ['CEO', 'VP', 'MD', 'CEO']}

df = pd.DataFrame(my_dict)


创建一个新的DataFrame作为

newdf = pd.DataFrame(df, columns=['name', 'age'])


您获得的结果与使用del / drop所获得的效果一样好

评论


从技术上讲这是正确的,但似乎不得不列出要保留的每一列而不是仅要删除的一(或几)列似乎很愚蠢。

–cs95
19年5月23日在17:24

#17 楼

当我们有一个带有不必要值的典型列名时,使用ilocdataframeslicing函数删除一列。
df = df.iloc[:,1:] # removing an unnamed index column

此处0是默认行,1是第一列,因此,1从此处开始并逐步执行默认值,因此:,1:是我们用于删除第一列的参数。