【问题标题】:Use regex to remove/exclude columns from dataframe - Python使用正则表达式从数据框中删除/排除列 - Python
【发布时间】:2019-11-10 09:21:41
【问题描述】:

我有一个可以从下面的代码生成的数据框

    df = pd.DataFrame({'person_id' :[1,2,3],'date1': ['12/31/2007','11/25/2009','10/06/2005'],'date1derived':[0,0,0],'val1':[2,4,6],'date2': ['12/31/2017','11/25/2019','10/06/2015'],'date2derived':[0,0,0],'val2':[1,3,5],'date3':['12/31/2027','11/25/2029','10/06/2025'],'date3derived':[0,0,0],'val3':[7,9,11]})

数据框如下图所示

我想删除名称中包含“派生”的列。我尝试了不同的正则表达式,但无法获得预期的输出。

    df = df.filter(regex='[^H\dDerived]+', axis=1)
    df = df.filter(regex='[^Derived]',axis=1)

你能告诉我正确的正则表达式吗?

【问题讨论】:

    标签: python regex python-3.x pandas dataframe


    【解决方案1】:
    df[[c for c in df.columns if 'derived' not in c ]]
    

    输出

       person_id       date1  val1       date2  val2       date3  val3
    0          1  12/31/2007     2  12/31/2017     1  12/31/2027     7
    1          2  11/25/2009     4  11/25/2019     3  11/25/2029     9
    2          3  10/06/2005     6  10/06/2015     5  10/06/2025    11
    

    【讨论】:

    • 一个简单的问题。假设在我的数据框中“date2”列是空的,我该如何删除该列?我的意思是当值为 NA 时,我们通常会删除行(记录),但如果 date2 列全部为 NA,我想删除“date2”列。你能告诉我怎么做吗?
    • pandas.pydata.org/pandas-docs/stable/reference/api/… 会有所帮助,使用 how='all' 和列名
    • 我的意思是,只有当列中的所有值都是“NA”时,我才想删除列。 iT 不应该删除 1 0r 2 NA's 的列
    • 是的,how="all" 是为了这个目的......通过文档你会得到它
    【解决方案2】:

    您可以使用零宽度的负前瞻来确保字符串 derived 不会出现在任何地方:

    ^(?!.*?derived)
    
    • ^ 匹配字符串的开头
    • (?!.*?derived) 是确保derived 不会出现在字符串中的负前瞻模式

    您的模式 [^Derived] 将匹配任何不属于 D/e/r/i/v/e/d 的单个字符。

    【讨论】:

      【解决方案3】:

      IIUC,您要删除的列中有 derived。应该这样做:

      df.drop(df.filter(like='derived').columns, 1)
      
      Out[455]:
         person_id       date1  val1       date2  val2       date3  val3
      0          1  12/31/2007     2  12/31/2017     1  12/31/2027     7
      1          2  11/25/2009     4  11/25/2019     3  11/25/2029     9
      2          3  10/06/2005     6  10/06/2015     5  10/06/2025    11
      

      【讨论】:

      • 您好,感谢您的回复。它将删除仅包含“派生”的所有列,并且不会删除包含“der”的列。我说的对吗?
      • 是的。它的名称中必须包含完整的单词 derived 才能删除。
      【解决方案4】:

      pd.Index.difference()df.filter()

      df[df.columns.difference(df.filter(like='derived').columns,sort=False)]
      

         person_id       date1  val1       date2  val2       date3  val3
      0          1  12/31/2007     2  12/31/2017     1  12/31/2027     7
      1          2  11/25/2009     4  11/25/2019     3  11/25/2029     9
      2          3  10/06/2005     6  10/06/2015     5  10/06/2025    11
      

      【讨论】:

      • 你好@anky_91 - 我能知道为什么我们需要使用 index.difference 吗?
      • @AVLES df.filter(like='derived').columns 为您提供具有 derived 的列,使用 pd.Index.difference(),我们发现 df.columns 和过滤列之间的区别。 sort=False 保持原来的顺序。 :)
      • 好的,通常我们drop的时候,列的顺序可以改变?
      • 如果列中的所有值都是 NA,您能否告诉我如何删除列?我知道我们有 dropna,但我们通常会删除记录(行)。如果所有值都是 NA,我想删除一列
      • @AVLES 不,不会,您也可以选择drop()。但是,任何返回 list 副本的算法都会更快,无论如何你都会切片 df.(IMO)
      【解决方案5】:

      在最新版本的 pandas 中,您可以在索引和列上使用字符串方法。在这里,str.endswith 似乎很合适。

      import pandas as pd
      
      df = pd.DataFrame({'person_id' :[1,2,3],'date1': ['12/31/2007','11/25/2009','10/06/2005'],
                         'date1derived':[0,0,0],'val1':[2,4,6],'date2': ['12/31/2017','11/25/2019','10/06/2015'],
                         'date2derived':[0,0,0],'val2':[1,3,5],'date3':['12/31/2027','11/25/2029','10/06/2025'],
                         'date3derived':[0,0,0],'val3':[7,9,11]})
      
      df = df.loc[:,~df.columns.str.endswith('derived')]
      
      print(df)
      

      O/P:

         person_id       date1  val1       date2  val2       date3  val3
      0          1  12/31/2007     2  12/31/2017     1  12/31/2027     7
      1          2  11/25/2009     4  11/25/2019     3  11/25/2029     9
      2          3  10/06/2005     6  10/06/2015     5  10/06/2025    11
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      • 2021-09-04
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      相关资源
      最近更新 更多