删除DataFrame中的列时,我使用:
del df['column_name']
这很有效 . 为什么我不能使用以下?
del df.column_name
由于您可以将列/系列作为 df.column_name 进行访问,因此我希望这可以正常工作 .
df.column_name
在pandas 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)
使用:
columns = ['Col1', 'Col2', ...] df.drop(columns, inplace=True, axis=1)
这将就地删除一个或多个列 . 请注意,在pandas v0.13中添加了 inplace=True 并且在这种情况下赢得't work on older versions. You' d必须返回结果:
inplace=True
df = df.drop(columns, axis=1)
寻找更有效的解决方案需要付出很多努力 . 在牺牲 df.drop(dlst, 1, errors='ignore') 的简单性的同时难以证明增加的复杂性
df.drop(dlst, 1, errors='ignore')
df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)
Preamble删除列在语义上与选择其他列相同 . 我将展示一些额外的方法来考虑 .
我还将重点关注一次删除多个列的一般解决方案,并允许尝试删除不存在的列 .
使用这些解决方案是一般性的,也适用于简单的情况 .
Setup考虑 pd.DataFrame df 和列表删除 dlst
pd.DataFrame
df
dlst
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.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
由于我等同于删除列以选择其他列,我将其分为两种类型:
标签选择
布尔选择
我们首先制作代表我们要保留的列的标签列表/数组,而不是我们想要删除的列 .
df.columns.difference(dlst)
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
np.setdiff1d(df.columns.values, dlst)
array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
df.columns.drop(dlst, errors='ignore')
list(set(df.columns.values.tolist()).difference(dlst))
# does not preserve order ['E', 'D', 'B', 'F', 'G', 'A', 'C']
[x for x in df.columns.values.tolist() if x not in dlst]
['A', 'B', 'C', 'D', 'E', 'F', 'G']
Columns from Labels为了比较选择过程,假设:
cols = [x for x in df.columns.values.tolist() if x not in dlst]
然后我们可以评估
df.loc[:, cols]
df[cols]
df.reindex(columns=cols)
df.reindex_axis(cols, 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.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)
Columns from Boolean为了比较
bools = [x not in dlst for x in df.columns.values.tolist()]
df.loc[: bools]
Robust Timing
功能
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)
Testing
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
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()
这与运行 df.drop(dlst, 1, errors='ignore') 所需的时间有关 . 看来,经过这么多努力,我们只能适度提高绩效 .
事实上,最好的解决方案在hack list(set(df.columns.values.tolist()).difference(dlst)) 上使用 reindex 或 reindex_axis . 紧随其后,仍然比 drop 好一点 np.setdiff1d .
reindex
reindex_axis
drop
np.setdiff1d
rs.idxmin().pipe( lambda x: pd.DataFrame( dict(idx=x.values, val=rs.lookup(x.values, x.index)), x.index ) ) idx val 10 (ridx, setdifflst) 0.653431 30 (ridxa, setdifflst) 0.746143 100 (ridxa, setdifflst) 0.816207 300 (ridx, setdifflst) 0.780157 1000 (ridxa, setdifflst) 0.861622
Another way of Deleting a Column in Pandas DataFrame
如果您不是在寻找就地删除,那么您可以通过使用 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得到的结果一样好
从版本0.16.1你可以做到
df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
删除第一,第二和第四列:
df.drop(df.columns[[0,1,3]], axis=1, inplace=True)
删除第一列:
df.drop(df.columns[[0]], axis=1, inplace=True)
有一个可选参数 inplace ,因此可以在不创建副本的情况下修改原始数据 .
inplace
Column selection, addition, deletion
删除列 column-name :
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 :
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 :
three = df.pop('three')
two A 2 B 5 C 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
点语法适用于JavaScript,但不适用于Python .
Python: del df['column_name']
JavaScript: del df['column_name'] or del df.column_name
由于Python中的语法限制,很难使 del df.column_name 工作变得简单 . del df[name] 被Python翻译为 df.__delitem__(name) .
del df[name]
df.__delitem__(name)
如果要从数据框( df )中删除单个列( col_name ),请尝试以下操作之一:
col_name
df = df.drop(col_name, axis=1)
要么
df.drop(col_name, axis=1, inplace=True)
如果要从数据框( df )中删除列( col_lst = [col_name_1,col_name_2,...] )列表,请尝试以下操作之一:
col_lst = [col_name_1,col_name_2,...]
df.drop(col_lst, axis=1, inplace=True)
df.drop(columns=col_lst, inplace=True)
在pandas中执行此操作的最佳方法是使用drop:
df = df.drop('column_name', 1)
其中 1 是轴编号(行为 0 ,列为 1 . )
1
0
要删除列而不必重新分配 df ,您可以执行以下操作:
df.drop('column_name', axis=1, inplace=True)
最后,要按列号而不是按列标签删除,请尝试删除,例如第1,第2和第4列:
df.drop(df.columns[[0, 1, 3]], axis=1) # df.columns is zero-based pd.Index
一个很好的补充是 drop columns only if they exist 的能力 . 这样,您可以覆盖更多用例,并且只会从传递给它的标签中删除现有列:
只需添加 errors='ignore' ,例如:
df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
大多数答案错过的实际问题是:
首先,我们需要了解这个问题,这需要我们深入研究python magic methods .
正如Wes在他的回答中指出 del df['column'] 映射到python魔法 df.__delitem__('column') 这是implemented in pandas to drop the column
del df['column']
df.__delitem__('column')
但是,正如上面关于python magic methods的链接所指出的那样:
事实上,del几乎不应该被使用,因为它被称为不稳定的环境;谨慎使用!
你可以说不应该使用或鼓励 del df['column_name'] ,因此甚至不应该考虑 del df.column_name .
但是,从理论上讲, del df.column_name 可以用the magic method delattr实现在熊猫中工作 . 然而,这确实引入了某些问题,这些问题已经实施,但程度较轻 .
如果我在名为“dtypes”或“columns”的数据框中定义列,该怎么办?
然后假设我想删除这些列 .
del df.dtypes 会使 __delattr__ 方法混淆,好像它应该删除"dtypes"属性或"dtypes"列 .
del df.dtypes
__delattr__
数据框是列的集合吗?
数据帧是行的集合吗?
列是数据框的属性吗?
是的,无论如何
不,但是如果你想要它,你可以使用 .ix , .loc 或 .iloc 方法 .
.ix
.loc
.iloc
也许,你想读数据吗?然后 yes ,除非该属性的名称已被属于该数据帧的另一个属性所采用 . 你想修改数据吗?然后 no .
你不能做 del df.column_name 因为pandas有一个非常广泛的架构需要重新考虑,以便这种认知失调不会发生在用户身上 .
不要使用df.column_name,它可能很漂亮,但它会导致认知失调
删除列有多种方法 .
应该有一个 - 最好只有一个 - 显而易见的方法 .
列有时是属性,但有时不属于 .
特殊情况不足以打破规则 .
del df.dtypes 是否删除了dtypes属性或dtypes列?
面对模棱两可,拒绝猜测的诱惑 .
Pandas版本0.21略微更改了drop方法,以包含 index 和 columns 参数以匹配 rename 和 reindex 方法的签名 .
index
columns
rename
df.drop(columns=['column_a', 'column_c'])
就个人而言,我更喜欢使用 axis 参数来表示列或索引,因为它是几乎所有pandas方法中使用的主要关键字参数 . 但是,现在您在版本0.21中添加了一些选项 .
axis
14 回答
在pandas 0.16.1中,只有在按照@eiTanLaVi发布的解决方案存在列时才能删除列 . 在该版本之前,您可以通过条件列表理解获得相同的结果:
使用:
这将就地删除一个或多个列 . 请注意,在pandas v0.13中添加了
inplace=True
并且在这种情况下赢得't work on older versions. You' d必须返回结果:TL; DR
寻找更有效的解决方案需要付出很多努力 . 在牺牲
df.drop(dlst, 1, errors='ignore')
的简单性的同时难以证明增加的复杂性Preamble
删除列在语义上与选择其他列相同 . 我将展示一些额外的方法来考虑 .
我还将重点关注一次删除多个列的一般解决方案,并允许尝试删除不存在的列 .
使用这些解决方案是一般性的,也适用于简单的情况 .
Setup
考虑
pd.DataFrame
df
和列表删除dlst
结果应如下所示:
由于我等同于删除列以选择其他列,我将其分为两种类型:
标签选择
布尔选择
标签选择
我们首先制作代表我们要保留的列的标签列表/数组,而不是我们想要删除的列 .
df.columns.difference(dlst)
np.setdiff1d(df.columns.values, dlst)
df.columns.drop(dlst, errors='ignore')
list(set(df.columns.values.tolist()).difference(dlst))
[x for x in df.columns.values.tolist() if x not in dlst]
Columns from Labels
为了比较选择过程,假设:
然后我们可以评估
df.loc[:, cols]
df[cols]
df.reindex(columns=cols)
df.reindex_axis(cols, 1)
所有评价为:
布尔切片
我们可以构造一个用于切片的布尔数组/列表
~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)
Columns from Boolean
为了比较
df.loc[: bools]
所有评价为:
Robust Timing
功能
Testing
这与运行
df.drop(dlst, 1, errors='ignore')
所需的时间有关 . 看来,经过这么多努力,我们只能适度提高绩效 .事实上,最好的解决方案在hack
list(set(df.columns.values.tolist()).difference(dlst))
上使用reindex
或reindex_axis
. 紧随其后,仍然比drop
好一点np.setdiff1d
.Another way of Deleting a Column in Pandas DataFrame
如果您不是在寻找就地删除,那么您可以通过使用
DataFrame(...)
函数指定列来创建新的DataFrame创建一个新的DataFrame作为
你得到的结果和del / drop得到的结果一样好
从版本0.16.1你可以做到
按索引删除
删除第一,第二和第四列:
删除第一列:
有一个可选参数
inplace
,因此可以在不创建副本的情况下修改原始数据 .弹出
Column selection, addition, deletion
删除列
column-name
:示例:
print df
:df.drop(df.columns[[0]], axis=1, inplace=True)
print df
:three = df.pop('three')
print df
:始终使用
[]
表示法是一种好习惯 . 一个原因是属性表示法(df.column_name
)不适用于编号索引:点语法适用于JavaScript,但不适用于Python .
Python:
del df['column_name']
JavaScript:
del df['column_name']
ordel df.column_name
由于Python中的语法限制,很难使
del df.column_name
工作变得简单 .del df[name]
被Python翻译为df.__delitem__(name)
.如果要从数据框(
df
)中删除单个列(col_name
),请尝试以下操作之一:要么
如果要从数据框(
df
)中删除列(col_lst = [col_name_1,col_name_2,...]
)列表,请尝试以下操作之一:要么
在pandas中执行此操作的最佳方法是使用drop:
其中
1
是轴编号(行为0
,列为1
. )要删除列而不必重新分配
df
,您可以执行以下操作:最后,要按列号而不是按列标签删除,请尝试删除,例如第1,第2和第4列:
一个很好的补充是 drop columns only if they exist 的能力 . 这样,您可以覆盖更多用例,并且只会从传递给它的标签中删除现有列:
只需添加 errors='ignore' ,例如:
大多数答案错过的实际问题是:
为什么我不能使用deldf.column_name?
首先,我们需要了解这个问题,这需要我们深入研究python magic methods .
正如Wes在他的回答中指出
del df['column']
映射到python魔法df.__delitem__('column')
这是implemented in pandas to drop the column但是,正如上面关于python magic methods的链接所指出的那样:
你可以说不应该使用或鼓励
del df['column_name']
,因此甚至不应该考虑del df.column_name
.但是,从理论上讲,
del df.column_name
可以用the magic method delattr实现在熊猫中工作 . 然而,这确实引入了某些问题,这些问题已经实施,但程度较轻 .示例问题
如果我在名为“dtypes”或“columns”的数据框中定义列,该怎么办?
然后假设我想删除这些列 .
del df.dtypes
会使__delattr__
方法混淆,好像它应该删除"dtypes"属性或"dtypes"列 .这个问题背后的建筑问题
数据框是列的集合吗?
数据帧是行的集合吗?
列是数据框的属性吗?
熊猫的答案:
是的,无论如何
不,但是如果你想要它,你可以使用
.ix
,.loc
或.iloc
方法 .也许,你想读数据吗?然后 yes ,除非该属性的名称已被属于该数据帧的另一个属性所采用 . 你想修改数据吗?然后 no .
TLDR;
你不能做
del df.column_name
因为pandas有一个非常广泛的架构需要重新考虑,以便这种认知失调不会发生在用户身上 .Protip:
不要使用df.column_name,它可能很漂亮,但它会导致认知失调
Python的引用适用于此处:
删除列有多种方法 .
列有时是属性,但有时不属于 .
del df.dtypes
是否删除了dtypes属性或dtypes列?熊猫0.21回答
Pandas版本0.21略微更改了drop方法,以包含
index
和columns
参数以匹配rename
和reindex
方法的签名 .就个人而言,我更喜欢使用
axis
参数来表示列或索引,因为它是几乎所有pandas方法中使用的主要关键字参数 . 但是,现在您在版本0.21中添加了一些选项 .