【问题标题】:How to calculate new vectorized column from bool and float columns in pandas dataframe?如何从 pandas 数据框中的 bool 和 float 列计算新的矢量化列?
【发布时间】:2023-03-12 04:19:01
【问题描述】:

我的 DataFrame 混合了浮点数和布尔值:

df = pd.DataFrame.from_csv("C:\....")

df['isActive'] = (df.turns >= 250) & (df.alivePct > 0) & (df.changePct > 0)

我想创建一个新列,如果 isActive == false 则 value = 0,否则该值等于某个计算量,如下所示:

df['interestingness'] = (df.changePct * df.alivePct) if df.isActive else 0

但是因为 df.isActive 是一个系列,我得到这个错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

三元 if/else 运算符似乎不能用于向量化操作。

我还能如何通过手动迭代来做到这一点?

(注意:一个简单的技巧是通过 df.isActive 将值设置为 0 为 False == 0。但是我想知道一个更通用的解决方案。)

【问题讨论】:

  • 你说的更一般是什么意思?另外,为什么它是一个黑客?它并没有比乘法更通用/更简单......
  • 另外,我的意思是,我看到您关心“如果布尔值不是 0 和 1 怎么办?”但我想,是的,只需将它们转换为 0 和 1 并返回乘法。 np.where 解决方案也不错。

标签: python pandas dataframe ternary-operator


【解决方案1】:

一个不同的解决方案,可能不那么可读但有效。

创建新的列/系列:

>>> df
   0      1  2
0  1   True  9
1  2  False  9
2  3   True  9
3  4  False  9
4  5   True  9
>>> df[3] = 0

使用面具

>>> mask = df[1]
>>> df[3][mask] = (df[0] * df[2])[mask]
>>> df
   0      1  2   3
0  1   True  9   9
1  2  False  9   0
2  3   True  9  27
3  4  False  9   0
4  5   True  9  45
>>> 

【讨论】:

    【解决方案2】:

    你可以使用np.where:

    import numpy as np
    df['interestingness'] = np.where(df.isActive, df.changePct * df.alivePct, 0)
    

    对于一维数组,np.where(condition, A, B) 是矢量化的等价于

    np.array([a if c else b for a,b,c in zip(condition, A, B)])
    

    Pandas 还提供了一个Series.where 方法供您使用:

    df['interestingness'] = (df.changePct * df.alivePct).where(df.isActive, 0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-28
      • 2020-11-08
      • 2021-03-03
      • 2019-10-02
      • 2018-07-28
      • 2023-04-06
      • 2014-02-16
      • 1970-01-01
      相关资源
      最近更新 更多