2014-11-06 62 views
1

我的数据帧具有浮点和布尔的混合:如何计算pandas数据框中bool和float列的新矢量化列?

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为假== 0,但是我想知道一个更通用的解决方案。)

+0

你是什么更普遍的是什么意思?另外,为什么它是黑客?它不会真正得到更多的普遍/比乘法少hacky ... – acushner 2014-11-06 15:40:15

+0

也,我的意思是,我看到你的关注,如“如果布尔人不是0和1?”但我会想,是的,只是将它们转换成零和一个,然后返回乘法。 'np.where'解决方案也不错。 – acushner 2014-11-06 15:44:17

回答

3

你可以使用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)]) 

熊猫还提供了一个Series.where方法,你可以使用:

df['interestingness'] = (df.changePct * df.alivePct).where(df.isActive, 0) 
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 
>>>