从pandas DataFrame中删除列

时间:2012-11-16 06:26:40

标签: python pandas dataframe

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

del df['column_name']

这很有效。为什么我不能使用以下内容?

del df.column_name

由于您可以{/ 1}}访问列/系列,我希望这可以正常工作。

19 个答案:

答案 0 :(得分:1752)

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

df = df.drop('column_name', 1)

其中1编号(行0和列1。)

要删除列而不必重新分配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 

答案 1 :(得分:573)

正如您所猜测的,正确的语法是

del df['column_name']

很难让del df.column_name仅仅因为Python中的语法限制而工作。 del df[name]被Python翻译为df.__delitem__(name)

答案 2 :(得分:204)

使用:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)

这将就地删除一个或多个列。请注意,pandas v0.13中添加了inplace=True,但旧版本无法使用df = df.drop(columns, axis=1) 。在这种情况下,您必须将结果分配回来:

{{1}}

答案 3 :(得分:92)

按索引删除

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

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

删除第一列:

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

有一个可选参数inplace,以便原始 无需创建副本即可修改数据。

弹出

Column selection, addition, deletion

删除专栏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

   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

   two
A    2
B    5
C    8

答案 4 :(得分:62)

这里提出的实际问题是:

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

首先,我们需要了解问题,这需要我们深入研究python magic methods

Wes在答案中指出del df['column']映射到python 魔术方法 df.__delitem__('column'),即implemented in pandas to drop the column

但是,正如上面关于python magic methods的链接所指出的那样:

  

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

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

但是,从理论上讲,del df.column_name可以使用the magic method __delattr__来实现大熊猫的工作。然而,这确实引入了某些问题,del df['column_name']实施已经存在的问题,但程度较轻。

示例问题

如果我在名为" dtypes"的数据框中定义一个列怎么办?或"列"。

然后假设我要删除这些列。

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

此问题背后的架构问题

  1. 是数据帧吗? 列的集合
  2. 数据框是的集合吗?
  3. 列是数据框的属性吗?
  4. 熊猫回答:

    1. 是的,无论如何
    2. 不,但如果您愿意,可以使用.ix.loc.iloc方法。
    3. 也许,你想读取数据吗?然后除非属性的名称已被属于该数据帧的另一个属性占用。您想要修改数据吗?然后
    4. TLDR;

      你无法做del df.column_name因为pandas有一个非常发展的架构,需要重新考虑才能使用户不会发生这种认知失调

      普罗蒂普:

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

      Python的禅宗引用适用于此:

      删除列有多种方法。

        

      应该有一个 - 最好只有一个 - 显而易见的方法。

      列有时是属性,但有时不属于。

        

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

      del df.dtypes是否会删除dtypes属性或dtypes列?

        

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

答案 5 :(得分:46)

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

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

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • 这是pandas 0.16.1以后的新内容。文档为here

答案 6 :(得分:39)

从版本0.16.1开始

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

答案 7 :(得分:26)

始终使用[]表示法是一种很好的做法。一个原因是属性表示法(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

答案 8 :(得分:20)

在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)

答案 9 :(得分:17)

Pandas 0.21+回答

Pandas版本0.21略微更改了drop方法,以包含<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="test" class="layout ui-resizable ui-droppable"> <div class="ui-resizable-handle ui-resizable-e"></div> <div class="ui-resizable-handle ui-resizable-s"></div> <div class="ui-resizable-handle ui-resizable-se"></div> <div id="obj1" class="ui-draggable ui-draggable-handle ui-draggable-dragging ui-resizable"> <img id="imgTest" class="photo"><img> <div class="ui-resizable-handle ui-resizable-e"></div> <div class="ui-resizable-handle ui-resizable-s"></div> <div class="ui-resizable-handle ui-resizable-se"></div> </div> </div>index参数,以匹配columnsrename方法的签名。

reindex

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

答案 10 :(得分:12)

TL; DR

为寻找更有效的解决方案付出了很多努力。在牺牲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

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

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

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

    1. df.columns.difference(dlst)

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

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

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

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

      ['A', 'B', 'C', 'D', 'E', 'F', 'G']
      
    6. 标签中的列
      为了比较选择过程,假设:

       cols = [x for x in df.columns.values.tolist() if x not in dlst]
      

      然后我们可以评估

      1. df.loc[:, cols]
      2. df[cols]
      3. df.reindex(columns=cols)
      4. df.reindex_axis(cols, 1)
      5. 所有评价为:

           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
        

        布尔切片

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

        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)
        5. 布尔列中的列
          为了便于比较

          bools = [x not in dlst for x in df.columns.values.tolist()]
          
          1. df.loc[: bools]
          2. 所有评价为:

               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')所需的时间有关。看来,经过这么努力,我们只能适度提高绩效。

            enter image description here

            如果最好的解决方案在黑客reindex上使用reindex_axislist(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
            

答案 11 :(得分:9)

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

假设 df 是一个数据框。

要删除的列= column0

代码:

df = df.drop(column0, axis=1)

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

代码:

df = df.drop([col1, col2, . . . , coln], axis=1)

我希望这会有所帮助。

答案 12 :(得分:7)

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)

答案 13 :(得分:5)

如果原始数据框 df 不太大,则没有内存限制,您只需要保留几列,或者,如果您事先不知道不需要的所有额外列的名称,那么最好只用所需的列创建一个新的数据框:

new_df = df[['spam', 'sausage']]

答案 14 :(得分:2)

点语法适用于JavaScript,但不适用于Python。

  • Python:Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.0 Created-By: 1.5.0_07-87 ("Apple Computer, Inc.") Built-By: wolf Name: common Specification-Title: swixml Specification-Vendor: swixml.org Specification-Version: 1.6 Implementation-Title: org.swixml Implementation-Vendor: swixml.org Implementation-Version: 1.6 beta 1 (#151)
  • JavaScript:del df['column_name'] del df['column_name']

答案 15 :(得分:1)

  

从多个数据帧中删除列

如果您是来这里寻找有关如何从DataFrames列表中删除一列(具有相同名称)的信息,则有几种方法可以这样做。

一种方法是遍历列表并就地修改每个DataFrame:

# In-place assignment
for df in df_list:
    df.drop('colname', axis=1, inplace=True)

或者,

for df in df_list: df.pop('colname')

或者,放下该列(不就地)并将结果分配回该列表位置。

# Reassigning a copy back to the list
for i, df in enumerate(df_list):
    df_list[i] = df.drop('colname', axis=1, inplace=True)

可复制代码示例

df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [4, 5, 7], 'C': ['a', 'b', 'c']})

df1
   A  B
0  1  4
1  2  5
2  3  6

df2
   A  C
0  4  a
1  5  b
2  7  c

df_list = [df1, df2]

# Drop column "A"
for df in df_list:
    df.drop('A', axis=1, inplace=True)

df1
   B
0  4
1  5
2  6

df2
   C
0  a
1  b
2  c

为什么for df in df_list: df = df.drop('colname', axis=1)(即循环内的重新分配)不起作用?

如其他答案所述,df.drop默认情况下返回副本。该副本将返回并重新分配给变量 df,而无需对原始副本进行任何修改。您要么必须使用df参数就地修改inplace=True,要么将副本明确地重新分配给该列表元素。

  

注意
    重要的是要了解变量和   对象。变量保存对对象的引用。变量可以是   重新分配以引用不同的对象,这与   修改对象本身。为了获得有关该主题的良好入门知识,我   建议阅读this article by Ned Batchelder.

答案 16 :(得分:0)

在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获得的结果一样好

答案 17 :(得分:0)

当我们有一个典型的带有不想要的值的列名时,使用ilocdataframe的{​​{1}}函数删除一列。

slicing

此处df = df.iloc[:,1:] # removing an unnamed index column 是默认行,而0是第一列,因此1从此处开始,步进采用默认值,因此,1是我们删除第一行的参数列。

答案 18 :(得分:-1)

您可以在2 ways.

中执行此操作
  1. del df['column_name']
  2. df.drop(columns=['column_name], axis=1, inplace=True)

学习愉快。