要删除DataFrame中的列,我可以成功使用:
del df['column_name']
但为什么我不能使用以下选项?
del df.column_name
由于可以通过df.column_name访问该系列,所以我希望这能奏效。
要删除DataFrame中的列,我可以成功使用:
del df['column_name']
但为什么我不能使用以下选项?
del df.column_name
由于可以通过df.column_name访问该系列,所以我希望这能奏效。
当前回答
如果原始数据帧df不太大,没有内存限制,只需要保留几列,或者,如果事先不知道不需要的所有额外列的名称,那么不妨创建一个只包含所需列的新数据帧:
new_df = df[['spam', 'sausage']]
其他回答
Use:
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)
在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)
Use:
columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)
这将在位删除一个或多个列。请注意,inplace=True是在panda v0.13中添加的,在旧版本中不起作用。在这种情况下,您必须重新分配结果:
df = df.drop(columns, axis=1)
在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一样好。
TL;博士
为找到一个稍微更有效的解决方案付出了很多努力。很难在牺牲df.drop的简单性的同时证明增加的复杂性(dlst,1,errors='ignore')
df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)
序言删除列在语义上与选择其他列相同。我将展示一些需要考虑的其他方法。
我还将重点介绍一次删除多个列并允许尝试删除不存在的列的一般解决方案。
使用这些解决方案是通用的,也适用于简单的情况。
安装程序考虑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.列.差异(dlst)索引([“A”、“B”、“C”、“D”、“E”、“F”、“G”],dtype=“对象”)np.setdiff1d(df.columns.values,dlst)数组(['A','B','C','D','E','F','G'],dtype=对象)df.columns.drop(dlst,errors='ignore')索引([“A”、“B”、“C”、“D”、“E”、“F”、“G”],dtype=“对象”)列表(set(df.columns.values.tolist()).difference(dlst))#不保留顺序[E','D','B','F','G','A','C'][如果x不在dlst中,则df.columns.values.tolist()中的x为x][‘A’、‘B’、‘C’、‘D’、‘E’、‘F’、‘G’]
标签中的列为了比较选择过程,假设:
cols = [x for x in df.columns.values.tolist() if x not in dlst]
然后我们可以评估
df.loc[:,列]df[列]df.rendex(列=列)df.rendex_axis(列,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.ind(数据列值,dlst)[df.columns.values.tolist()中的x不在dlst中](df.columns.values[:,None]!=dlst).all(1)
来自布尔值的列为了便于比较
bools = [x not in dlst for x in df.columns.values.tolist()]
df.loc[:bools]
所有评估结果如下:
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
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')。经过这么多努力,我们似乎只会适度提高绩效。
如果事实上,最好的解决方案在黑客列表上使用reindex或reindex_axis(set(df.columns.values.tolist()).difference(dlst))。最后一秒,比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