按列名从pandas DataFrame中删除列

Joh*_*ohn 1136 python dataframe pandas

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

del df['column_name']
Run Code Online (Sandbox Code Playgroud)

这很有效.为什么我不能使用以下?

del df.column_name
Run Code Online (Sandbox Code Playgroud)

由于您可以访问列/系列df.column_name,我希望这可以工作.

Lon*_*Rob 1920

在熊猫中执行此操作的最佳方法是使用drop:

df = df.drop('column_name', 1)
Run Code Online (Sandbox Code Playgroud)

其中1数(0行和1列的).

要删除列而不必重新分配,df您可以执行以下操作:

df.drop('column_name', axis=1, inplace=True)
Run Code Online (Sandbox Code Playgroud)

最后,要按列而不是列标签删除,请尝试删除,例如第1列,第2列和第4列:

df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 
Run Code Online (Sandbox Code Playgroud)

  • 真正的@Paul,但由于问题的标题,大多数到达这里的人都是通过尝试找出如何删除列来实现的. (90认同)
  • 出于某种原因,这是推荐给`del`吗? (70认同)
  • @beardc`drop` over`del`的另一个优点是`drop`允许你一次删除多个列,执行或不执行操作,还删除任何轴上的记录(特别适用于3-D矩阵或`Panel`) (20认同)
  • 虽然这种删除方法有其优点,但这个答案并没有真正回答被问到的问题. (17认同)
  • 我没有想过以这种方式阅读它,但我想我比SQL更习惯于pythonisms.也许取决于谁会阅读它?我也是在可能的情况下保存击键的粉丝,其他一切都相同:) (3认同)
  • `drop`优于`del`的另一个优势是[drop](http://pandas.pydata.org/pandas-docs/stable/generation/pandas.DataFrame.drop.html)是pandas API的一部分,包含文档。 (3认同)
  • 请注意,在 3.7 中,`df = df.drop('column_name', 1)` 会抛出“FutureWarning:在 pandas 的未来版本中,除参数 'labels' 之外的所有 DataFrame.drop 参数都将仅是关键字”。 2. 指定 `df = df.drop('column_name', axis=1)` 以避免警告, (2认同)

Wes*_*ney 704

del df.column_name由于Python中的语法限制,很难简单地完成工作.del df[name]df.__delitem__(name)Python 翻译成了封面.

  • 我意识到这是一个超级老的"答案",但我的好奇心被激怒了 - *为什么*是Python的语法限制?`class A(object):def __init __(self):self.var = 1`设置一个类,然后`a = A(); del a.var`工作得很好...... (23认同)
  • @dwanderson的不同之处在于,当要删除列时,DataFrame需要自己处理"如何操作".在`del df [name]`的情况下,它被转换为`df .__ delitem __(name)`,这是DataFrame可以实现和修改其需要的方法.在`del df.name`的情况下,成员变量被删除,而没有机会运行任何自定义代码.考虑一下你自己的例子 - 你能得到`del a.var`来导致打印"删除变量"吗?如果可以,请告诉我如何.我不能:) (8认同)
  • @Yonatan您可以使用https://docs.python.org/3/reference/datamodel.html#object.__delattr__或描述符:https://docs.python.org/3/howto/descriptor.html (6认同)
  • @Yonatan Eugene的评论也适用于Python 2; 描述符自2.2以来一直在Python 2中,并且满足您的要求是微不足道的;) (5认同)
  • 这个答案并不完全正确 - `pandas` 开发人员_没有_,但这并不意味着它很难做到。 (3认同)
  • 当您保存 csv 并想要再次读取它时,使用此答案可能会导致标记化问题。使用 @LondonRob 描述的“df.drop()”是正确的方法。 (2认同)

Kri*_*kar 224

使用:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)
Run Code Online (Sandbox Code Playgroud)

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

df = df.drop(columns, axis=1)
Run Code Online (Sandbox Code Playgroud)

  • 关于这个答案的注释:如果使用'list',则应删除方括号:`df.drop(list,inplace = True,axis = 1)` (3认同)

jez*_*ael 101

按索引删除

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

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)
Run Code Online (Sandbox Code Playgroud)

删除第一列:

df.drop(df.columns[[0]], axis=1, inplace=True)
Run Code Online (Sandbox Code Playgroud)

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

膨化

列选择,添加,删除

删除列column-name:

df.pop('column-name')
Run Code Online (Sandbox Code Playgroud)

例子:

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

print df:

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9
Run Code Online (Sandbox Code Playgroud)

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

   two  three
A    2      3
B    5      6
C    8      9
Run Code Online (Sandbox Code Playgroud)

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

   two
A    2
B    5
C    8
Run Code Online (Sandbox Code Playgroud)

  • @Yugi您可以使用转置数据框.ex - `df.T.pop('A')` (2认同)

fir*_*ynx 68

大多数答案错过的实际问题是:

为什么我不能使用del df.column_name

首先我们需要了解这个问题,这需要我们深入研究python魔术方法.

正如Wes在他的答案中指出的那样,del df['column']python magic方法 df.__delitem__('column')在pandas中实现的,用于删除列

但是,正如上面关于python魔术方法的链接所指出的那样:

实际上,del应该几乎不会被使用,因为它被称为不稳定的环境; 谨慎使用!

你可以争辩del df['column_name']说不应该使用或鼓励,因此del df.column_name甚至不应该考虑.

然而,从理论上讲,del df.column_name可以Implemeted一个使用大熊猫工作魔术方法__delattr__.然而,这确实引入了某些问题,del df['column_name']实施已经存在的问题,但程度较轻.

示例问题

如果我在名为"dtypes"或"columns"的数据框中定义列,该怎么办?

然后假设我想删除这些列.

del df.dtypes会使__delattr__方法混淆,好像它应该删除"dtypes"属性或"dtypes"列.

这个问题背后的建筑问题

  1. 数据框是的集合吗?
  2. 数据帧是的集合吗?
  3. 列是数据框的属性吗?

熊猫的答案:

  1. 是的,无论如何
  2. 没有,但是如果你希望它是,你可以使用.ix,.loc.iloc方法.
  3. 也许,你想数据吗?然后,除非该属性的名称已被属于该数据帧的另一个属性所采用.你想修改数据吗?然后没有.

TLDR;

你不能这样做,del df.column_name因为大熊猫有一个非常广泛的架构需要重新考虑,以便这种认知失调不会发生在用户身上.

专家提示:

不要使用df.column_name,它可能很漂亮,但它会导致认知失调

Python的禅宗引用适合这里:

删除列有多种方法.

应该有一个 - 最好只有一个 - 明显的方法来做到这一点.

列有时属性,但有时不属性.

特殊情况不足以打破规则.

del df.dtypes删除dtypes属性还是dtypes列?

面对模棱两可,拒绝猜测的诱惑.

  • 实际上解决了原始问题的“为什么”部分。我已经实现了 pandas dataframe 的子类。这样做将教会您这个答案的重要部分。区分属性和列名是一个大问题。df.a 留下了歧义,即 a 是属性还是列名。然而,正如 pandas 所写的那样,df["a"] 只能是一列。 (2认同)

eiT*_*aVi 54

一个很好的补充是只有在存在时才删除列的能力.这样,您可以覆盖更多用例,并且只会从传递给它的标签中删除现有列:

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

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
Run Code Online (Sandbox Code Playgroud)
  • 这是pandas 0.16.1以后的新内容.文档在这里.


sus*_*mit 41

从版本0.16.1你可以做到

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
Run Code Online (Sandbox Code Playgroud)

  • 这也支持删除多个列,其中一些不需要存在(即没有引发错误``errors ='ignore'``)``df.drop(['column_1','column_2'],axis = 1,inplace = True,errors ='ignore')``,如果这样的应用程序需要! (3认同)

And*_*den 29

始终使用[]符号是一种好习惯.一个原因是属性notation(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
Run Code Online (Sandbox Code Playgroud)


Ted*_*rou 22

熊猫0.21+答案

Pandas版本0.21 drop稍微改变了方法,包括indexcolumns参数匹配renamereindex方法的签名.

df.drop(columns=['column_a', 'column_c'])
Run Code Online (Sandbox Code Playgroud)

就个人而言,我更喜欢使用axis参数来表示列或索引,因为它是几乎所有pandas方法中使用的主要关键字参数.但是,现在你在版本0.21中有一些新的选择.


Ale*_*der 21

在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)
Run Code Online (Sandbox Code Playgroud)


小智 21

用:

df.drop('columnname', axis =1, inplace = True)
Run Code Online (Sandbox Code Playgroud)

或者你可以去

del df['colname']
Run Code Online (Sandbox Code Playgroud)

根据列号删除多列

df.drop(df.iloc[:,1:3], axis = 1, inplace = True)
Run Code Online (Sandbox Code Playgroud)

根据列名删除多个列

df.drop(['col1','col2',..'coln'], axis = 1, inplace = True)
Run Code Online (Sandbox Code Playgroud)


piR*_*red 14

TL; DR

寻找更有效的解决方案需要付出很多努力.难以证明增加复杂性同时牺牲简单性df.drop(dlst, 1, errors='ignore')

df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)
Run Code Online (Sandbox Code Playgroud)

前导
删除列在语义上与选择其他列相同.我将展示一些额外的方法来考虑.

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

使用这些解决方案是一般性的,也适用于简单的情况.


设置
考虑pd.DataFrame df并删除列表dlst

df = pd.DataFrame(dict(zip('ABCDEFGHIJ', range(1, 11))), range(3))
dlst = list('HIJKLM')
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
dlst

['H', 'I', 'J', 'K', 'L', 'M']
Run Code Online (Sandbox Code Playgroud)

结果应如下所示:

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
Run Code Online (Sandbox Code Playgroud)

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

  1. 标签选择
  2. 布尔选择

标签选择

我们首先制作代表我们要保留的列的标签列表/数组,而不是我们想要删除的列.

  1. df.columns.difference(dlst)

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
    Run Code Online (Sandbox Code Playgroud)
  2. np.setdiff1d(df.columns.values, dlst)

    array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
    
    Run Code Online (Sandbox Code Playgroud)
  3. df.columns.drop(dlst, errors='ignore')

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
    Run Code Online (Sandbox Code Playgroud)
  4. list(set(df.columns.values.tolist()).difference(dlst))

    # does not preserve order
    ['E', 'D', 'B', 'F', 'G', 'A', 'C']
    
    Run Code Online (Sandbox Code Playgroud)
  5. [x for x in df.columns.values.tolist() if x not in dlst]

    ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    
    Run Code Online (Sandbox Code Playgroud)

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

 cols = [x for x in df.columns.values.tolist() if x not in dlst]
Run Code Online (Sandbox Code Playgroud)

然后我们可以评估

  1. df.loc[:, cols]
  2. df[cols]
  3. df.reindex(columns=cols)
  4. 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
Run Code Online (Sandbox Code Playgroud)

布尔切片

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

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

来自布尔
的列为了进行比较

bools = [x not in dlst for x in df.columns.values.tolist()]
Run Code Online (Sandbox Code Playgroud)
  1. 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
Run Code Online (Sandbox Code Playgroud)

强大的时间

功能

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)
Run Code Online (Sandbox Code Playgroud)

测试

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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

事实上,最好的解决方案使用reindexreindex_axis黑客攻击list(set(df.columns.values.tolist()).difference(dlst)).紧随其后,仍然非常轻微比dropnp.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
Run Code Online (Sandbox Code Playgroud)


Lit*_*jan 13

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

假设df是一个数据框。

要删除的列 = column0

代码:

df = df.drop(column0, axis=1)
Run Code Online (Sandbox Code Playgroud)

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

代码:

df = df.drop([col1, col2, . . . , coln], axis=1)
Run Code Online (Sandbox Code Playgroud)


ccp*_*zza 6

如果你的原始数据框df不是太大,你没有内存限制,你只需要保留几列,或者,如果你事先不知道你不需要的所有额外列的名称,那么你可能以及创建一个仅包含您需要的列的新数据框:

new_df = df[['spam', 'sausage']]
Run Code Online (Sandbox Code Playgroud)


Sye*_*dri 5

当我们有一个包含不需要的值的典型列名时,使用和iloc函数删除列:dataframeslicing

df = df.iloc[:,1:] # Removing an unnamed index column
Run Code Online (Sandbox Code Playgroud)

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