要删除DataFrame中的列,我可以成功使用:
del df['column_name']
但为什么我不能使用以下选项?
del df.column_name
由于可以通过df.column_name访问该系列,所以我希望这能奏效。
要删除DataFrame中的列,我可以成功使用:
del df['column_name']
但为什么我不能使用以下选项?
del df.column_name
由于可以通过df.column_name访问该系列,所以我希望这能奏效。
当前回答
在Pandas 0.16.1+中,只有当列按照eiTan LaVi发布的解决方案存在时,才能删除它们。在此版本之前,您可以通过条件列表理解获得相同的结果:
df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df],
axis=1, inplace=True)
其他回答
这里的大多数答案都忽略了实际提出的问题:
为什么不能使用del df.column_name?
首先,我们需要了解这个问题,这需要我们深入研究Python的神奇方法。
正如韦斯在回答中指出的那样,deldf['column']映射到Python的神奇方法df__delitem__('column'),它在Pandas中实现以删除列。
然而,正如上面关于Python魔术方法的链接中所指出的:
事实上,__del__几乎永远不应该被使用,因为它被称为;小心使用!
您可以认为不应该使用或鼓励del df['column_name],因此甚至不应该考虑del df.column_name。
然而,理论上,deldf.column_name可以使用魔术方法__delattr_在Pandas中实现。然而,这确实会带来某些问题,deldf['column_name]实现已经存在的问题,但程度较低。
示例问题
如果我在数据帧中定义了一个名为“dtypes”或“columns”的列,该怎么办?
然后假设我想删除这些列。
deldf.dtypes会使__delattr_方法混淆,好像它应该删除“dtypes”属性或“dtype”列一样。
这个问题背后的建筑问题
数据帧是列的集合吗?数据帧是行的集合吗?列是数据帧的属性吗?
熊猫回答:
是的,在所有方面不,但如果您想这样做,可以使用.ix、.loc或.iloc方法。也许,你想读取数据吗?那么是的,除非该属性的名称已经被属于数据帧的另一个属性所采用。是否要修改数据?那就没有了。
太长,读不下去了
你不能做deldf.column_name,因为Pandas有一个相当广泛的架构,需要重新考虑,以避免用户出现这种认知失调。
专业提示:
不要使用df.column_name。它可能很漂亮,但会导致认知失调。
Python之禅引用如下:
删除列有多种方法。
应该有一种——最好只有一种——明显的方法来实现。
列有时是属性,但有时不是。
特殊情况不足以打破规则。
del df.dtypes是否删除dtypes属性或dtypes列?
面对模棱两可的问题,拒绝猜测。
在Pandas DataFrame中删除列的另一种方法
如果您不希望就地删除,则可以通过使用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一样好。
Pandas 0.21+答案
Pandas 0.21版略微更改了drop方法,以包括索引和列参数,以匹配重命名和重新索引方法的签名。
df.drop(columns=['column_a', 'column_c'])
就我个人而言,我更喜欢使用axis参数来表示列或索引,因为它是几乎所有panda方法中使用的主要关键字参数。但是,现在您在0.21版中增加了一些选择。
Use:
columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)
这将在位删除一个或多个列。请注意,inplace=True是在panda v0.13中添加的,在旧版本中不起作用。在这种情况下,您必须重新分配结果:
df = df.drop(columns, axis=1)
在Pandas中执行此操作的最佳方法是使用drop:
df = df.drop('column_name', axis=1)
其中1是轴号(0表示行,1表示列。)
或者,drop()方法接受索引/列关键字作为指定轴的替代方法。所以我们现在可以做:
df = df.drop(columns=['column_nameA', 'column_nameB'])
这是在v0.21.0中引入的(2017年10月27日)
要删除列而不必重新分配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
同时使用列的“text”语法:
df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)