【问题标题】:Pandas select columns with regex and divide by value熊猫使用正则表达式选择列并按值除
【发布时间】:2018-06-23 19:36:24
【问题描述】:

我想将某些与正则表达式匹配的列中的所有值除以某个值,并且仍然拥有完整的数据框。

可以在这里找到:How to select columns from dataframe by regex,例如所有以 d 开头的列都可以选择:

df.filter(regex=("d.*"))

现在我选择了我需要的列,我想要例如将值除以 2。可以使用以下代码:

df.filter(regex=("d.*")).divide(2)

但是,如果我尝试像这样更新我的数据框,它会给出 can't assign to function call:

df.filter(regex=("d.*")) = df.filter(regex=("d.*")).divide(2)

如何正确更新我现有的 df?

【问题讨论】:

标签: python regex pandas


【解决方案1】:

以下技术不限于与过滤器一起使用,并且可以更广泛地应用。

设置
我将使用 @cᴏʟᴅsᴘᴇᴇᴅ 设置
df成为:

   d1  d2  abc
0   5   1    8
1  13   8    6
2   9   4    7
3   9  16   15
4   1  20    9

就地更新
使用 pd.DataFrame.update
update 将采用参数数据帧并更改索引和列值与参数匹配的调用数据帧。

df.update(df.filter(regex='d.*') / 3)
df

         d1        d2  abc
0  1.666667  0.333333    8
1  4.333333  2.666667    6
2  3.000000  1.333333    7
3  3.000000  5.333333   15
4  0.333333  6.666667    9

内联复制
使用pd.DataFrame.assign
我使用双 splat ** 将参数数据框解压缩到一个字典中,其中列名是键,作为列的系列是值。这与assign 所需的签名相匹配,并覆盖生成的副本中的那些列。简而言之,这是调用数据帧的副本,其中列被适当覆盖。

df.assign(**df.filter(regex='d.*').div(3))

         d1        d2  abc
0  1.666667  0.333333    8
1  4.333333  2.666667    6
2  3.000000  1.333333    7
3  3.000000  5.333333   15
4  0.333333  6.666667    9

【讨论】:

  • 很高兴收到您不时的回答。 :)
  • 谢谢@cᴏʟᴅsᴘᴇᴇᴅ!
  • 他们都是很好的答案,但是由于这个是最通用的,而且代码很短,我会接受这个。
【解决方案2】:

我认为您需要提取列名并分配:

df[df.filter(regex=("d.*")).columns] = df.filter(regex=("d.*")).divide(2)

或者:

cols = df.columns[df.columns.str.contains('^d.*')]
df[cols] /=2

【讨论】:

    【解决方案3】:

    使用df.columns.str.startswith

    c = df.columns.str.startswith('d')    
    df.loc[:, c] /= 2
    

    例如,考虑 -

    df
    
       d1  d2  abc
    0   5   1    8
    1  13   8    6
    2   9   4    7
    3   9  16   15
    4   1  20    9
    
    c = df.columns.str.startswith('d')  
    c
    array([ True,  True, False], dtype=bool)
    
    df.loc[:, c] /= 3    # 3 instead of 2, just for example
    df
    
             d1        d2  abc
    0  1.666667  0.333333    8
    1  4.333333  2.666667    6
    2  3.000000  1.333333    7
    3  3.000000  5.333333   15
    4  0.333333  6.666667    9
    

    如果需要传递正则表达式,请使用str.contains -

    c = df.columns.str.contains(p) # p => your pattern
    

    你的其余代码如下。

    【讨论】:

    • 也谢谢。您的答案解决了示例问题,但我使用了它,因为它被简化了。我自己的代码需要一个更复杂的正则表达式,所以startswith 不能解决这个问题。
    • @NumesSanguis 然后使用df.columns.str.contains,并传递一个正则表达式。还是更简单。
    • df.loc[:, c] /= 2 很可爱,没想到那个!
    • @RobinNemeth 是的,你会先在我的回答中看到它;)
    猜你喜欢
    • 2019-10-19
    • 2018-04-30
    • 2017-06-18
    • 2016-12-31
    • 2019-01-09
    • 1970-01-01
    • 2015-11-18
    • 2018-07-23
    相关资源
    最近更新 更多