要删除DataFrame中的列,我可以成功使用:

del df['column_name']

但为什么我不能使用以下选项?

del df.column_name

由于可以通过df.column_name访问该系列,所以我希望这能奏效。


当前回答

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)

其他回答

从版本0.16.1开始,您可以

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

通过使用自动补全或“IntelliSense”而不是字符串文字来获得优势:

del df[df.column1.name]

# or

df.drop(df.column1.name, axis=1, inplace=True)

它适用于当前的Pandas版本。

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

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

使用数据帧和切片的iloc函数删除列,当我们有一个带有不需要的值的典型列名时:

df = df.iloc[:,1:] # Removing an unnamed index column

这里0是默认行,1是第一列,因此:,1:是删除第一列的参数。

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