如何从pandas数据帧中的bool和float列计算新的矢量化列



My DataFrame混合了浮点和布尔值:

df = pd.DataFrame.from_csv("C:....")
df['isActive'] = (df.turns >= 250) & (df.alivePct > 0) & (df.changePct > 0)

我想创建一个新列,如果isActive==false,则值=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。不过,我想知道一个更通用的解决方案。)

您可以使用np.where:

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

对于1D阵列,np.where(condition, A, B)是的矢量化等价物

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

Pandas还提供了一个系列。您可以使用的方法:

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

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

创建新列/系列:

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

最新更新