【问题标题】:Deleting multiple columns based on column names in Pandas根据 Pandas 中的列名删除多个列
【发布时间】:2015-04-16 19:02:21
【问题描述】:

我有一些数据,当我导入它时,我得到以下不需要的列我正在寻找一种简单的方法来删除所有这些

   'Unnamed: 24', 'Unnamed: 25', 'Unnamed: 26', 'Unnamed: 27',
   'Unnamed: 28', 'Unnamed: 29', 'Unnamed: 30', 'Unnamed: 31',
   'Unnamed: 32', 'Unnamed: 33', 'Unnamed: 34', 'Unnamed: 35',
   'Unnamed: 36', 'Unnamed: 37', 'Unnamed: 38', 'Unnamed: 39',
   'Unnamed: 40', 'Unnamed: 41', 'Unnamed: 42', 'Unnamed: 43',
   'Unnamed: 44', 'Unnamed: 45', 'Unnamed: 46', 'Unnamed: 47',
   'Unnamed: 48', 'Unnamed: 49', 'Unnamed: 50', 'Unnamed: 51',
   'Unnamed: 52', 'Unnamed: 53', 'Unnamed: 54', 'Unnamed: 55',
   'Unnamed: 56', 'Unnamed: 57', 'Unnamed: 58', 'Unnamed: 59',
   'Unnamed: 60'

它们由 0 索引索引,所以我尝试了类似

    df.drop(df.columns[[22, 23, 24, 25, 
    26, 27, 28, 29, 30, 31, 32 ,55]], axis=1, inplace=True)

但这不是很有效。我尝试编写一些 for 循环,但这让我觉得 Pandas 的行为很糟糕。所以我在这里问这个问题。

我见过一些类似的例子 (Drop multiple columns pandas) 但这并不能回答我的问题。

【问题讨论】:

  • 什么意思,高效?是不是跑得太慢了?如果您的问题是您不想获取要删除的所有列的索引,请注意您可以只给df.drop 列名列表:df.drop(['Unnamed: 24', 'Unnamed: 25', ...], axis=1)
  • 只对感兴趣的列进行子集化会不会更容易:即df = df[cols_of_interest],否则您可以按列切片df并获取列df.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)
  • 我的意思是打字效率低或“代码不好”
  • 可能值得注意的是,在大多数情况下,保留所需的列然后删除不需要的列会更容易:df = df['col_list']

标签: python pandas


【解决方案1】:

目前最简单的方法是:

yourdf.drop(['columnheading1', 'columnheading2'], axis=1, inplace=True)

【讨论】:

  • 我在我的一些代码中使用了这种格式,我收到了SettingWithCopyWarning 警告?
  • @KillerSnail,保存忽略。为避免错误,请尝试: df = df.drop(['colheading1', 'colheading2'], axis=1)
  • 术语axis 解释:stackoverflow.com/questions/22149584/…。本质上,axis=0 被称为“按列”,axis=1 被称为“按行”。
  • inplace=True表示DataFrame修改到位。
  • @Killernail 如果您不想收到警告,请执行yourdf = yourdf.drop(['columnheading1', 'columnheading2'], axis=1)
【解决方案2】:

我不知道您所说的效率低下是什么意思,但如果您的意思是打字,那么只需选择感兴趣的列并分配回 df 会更容易:

df = df[cols_of_interest]

其中cols_of_interest 是您关心的列的列表。

或者您可以对列进行切片并将其传递给drop

df.drop(df.ix[:,'Unnamed: 24':'Unnamed: 60'].head(0).columns, axis=1)

head 的调用只选择了 0 行,因为我们只对列名而不是数据感兴趣

更新

另一种方法:使用来自str.contains 的布尔掩码并将其反转以屏蔽列会更简单:

In [2]:
df = pd.DataFrame(columns=['a','Unnamed: 1', 'Unnamed: 1','foo'])
df

Out[2]:
Empty DataFrame
Columns: [a, Unnamed: 1, Unnamed: 1, foo]
Index: []

In [4]:
~df.columns.str.contains('Unnamed:')

Out[4]:
array([ True, False, False,  True], dtype=bool)

In [5]:
df[df.columns[~df.columns.str.contains('Unnamed:')]]

Out[5]:
Empty DataFrame
Columns: [a, foo]
Index: []

【讨论】:

  • 当我尝试执行 ~df.columns... (TypeError: bad operand type for unary ~: 'str') 或 df.columns.str.contains... (AttributeError :“索引”对象没有属性“str”)。任何想法为什么会这样?
  • @EdChum 我可以创建 df = df[cols_of_interest],其中 cols_of_interest 在每次 for 循环迭代时添加一个列名?跨度>
  • @Victor 不,如果你这样做,你应该用你的新专栏覆盖你的df,你应该append,但我不太明白你的问题,你应该在 SO 上发布一个真正的问题而不是作为评论询问,因为它在 SO 上的形式很糟糕
  • @EdChum 你说得对。我已经创建了这个问题,我试图通过搜索 SO 的不同部分来解决它。链接在这里 !任何贡献都会帮助stackoverflow.com/questions/48923915/…
【解决方案3】:

我个人最喜欢的,比我在这里看到的答案更容易(针对多个专栏):

df.drop(df.columns[22:56], axis=1, inplace=True)

【讨论】:

  • 这应该是答案。最简洁、最易阅读,具有直接的原生 Pandas 索引语法。
  • 这个答案旁边应该有绿色勾号,而不是其他答案。
  • 小修正(除非我弄错了):第二个代码块应该有 'inplace=True' 而不是 'inplace=1'。
【解决方案4】:

这可能是做你想做的事的好方法。它将删除标题中包含“未命名”的所有列。

for col in df.columns:
    if 'Unnamed' in col:
        del df[col]

【讨论】:

  • 这个for col in df.columns:可以简化为for col in df:,OP也没有说明其他列的命名方案是什么,它们都可以包含“未命名”,这也是低效的一次删除一列
  • 当然效率不高,但只要我们不处理庞大的数据帧,它就不会产生重大影响。这种方法的优点是它很容易记住并且编码速度很快——而创建一个你想要保留的列的列表可能会很痛苦。
  • 我认为这可能在大型 df 上性能最高,因为您不必使用 inplace = True 制作本地副本
【解决方案5】:

您可以一口气完成:

df.drop([col for col in df.columns if "Unnamed" in col], axis=1, inplace=True)

与上述解决方案相比,这涉及更少的移动/复制对象。

【讨论】:

    【解决方案6】:

    不确定是否在任何地方都提到过这个解决方案,但一种方法是pandas.Index.difference

    >>> df = pd.DataFrame(columns=['A','B','C','D'])
    >>> df
    Empty DataFrame
    Columns: [A, B, C, D]
    Index: []
    >>> to_remove = ['A','C']
    >>> df = df[df.columns.difference(to_remove)]
    >>> df
    Empty DataFrame
    Columns: [B, D]
    Index: []
    

    【讨论】:

      【解决方案7】:

      您可以将列名作为列表传递,并将轴指定为 0 或 1

      • axis=1:沿行
      • axis=0:沿列
      • 默认轴=0

        data.drop(["Colname1","Colname2","Colname3","Colname4"],axis=1)

      【讨论】:

        【解决方案8】:

        简单易行。删除 22 日之后的所有列。

        df.drop(columns=df.columns[22:]) # love it
        

        【讨论】:

        • 要修改df就地,添加标志inplace=True,这样df.drop(columns=df.columns[22:], inplace=True)
        【解决方案9】:

        以下对我有用:

        for col in df:
            if 'Unnamed' in col:
                #del df[col]
                print col
                try:
                    df.drop(col, axis=1, inplace=True)
                except Exception:
                    pass
        

        【讨论】:

          【解决方案10】:

          df = df[[col for col in df.columns if not ('Unnamed' in col)]]

          【讨论】:

          • 这与 Peter 的类似,只是将不需要的列过滤掉而不是丢弃。
          猜你喜欢
          • 2021-12-06
          • 1970-01-01
          • 2016-11-01
          • 2021-09-06
          • 1970-01-01
          • 2022-10-15
          • 2020-12-11
          • 2013-08-12
          • 1970-01-01
          相关资源
          最近更新 更多