我有一个包含3列的df:v1,v2,v3;其中
v1=[a,b,c,a]
v2=[d,d,f,n]
v3=[a,k,i,j]
我喜欢做的是根据第v1~v3列中的条件创建新列。
我可以做单一条件,
df['v1_a']=np.where(df['v1']=='a',1,0)
它提供了一个名为'v1_a'
的新列1/0
但是,如果我想基于多个条件创建新列,则不起作用:
df['v2_flag']=np.where(df['v2']=='f' or df['v2']=='h',1,0)
我该如何做到这一点?
答案 0 :(得分:2)
如果您使用多个条件,则会收到以下ValueError
,因为np.where()
不接受多个条件:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
所以我建议您使用np.logical_or
。
df['v2_flag']=np.where(np.logical_or(df['v2']=='f',df['v2']=='h'),1,0)
也请参阅以下示例:
>>> a=np.array([2,2,2,5,7,8,1,4,2,3,4,5,6])
>>> np.where(np.logical_or(a==5,a==2),a,0)
array([2, 2, 2, 5, 0, 0, 0, 0, 2, 0, 0, 5, 0])
答案 1 :(得分:2)
在python中and
和or
只能提供单个结果,并且无法覆盖模块的其他用途,例如您要尝试的巨大的逐行比较。
您需要使用符号&
(和)和|
(或),它们通常用于逐位比较。这些已经被大熊猫重新定位为逐行比较,这实际上是有道理的,因为它类似于逐位比较。这更像是一个幸福的巧合,因为这些主要是因为这些可以被模块覆盖。
由于这些和平等的优先级,你需要在每个术语周围使用括号,否则它会在|
之前计算==
,这不是你想要的。你可以使用这样的东西:
df['v2_flag']=np.where((df['v2']=='f')|(df['v2']=='h'),1,0)
答案 2 :(得分:0)
df['v2']=='f' or df['v2']=='h'
在到达np.where
之前引发ValueError 。 or
导致Python在布尔上下文中评估df['v2']=='f'
和df['v2']=='h'
。但是Pandas Series
和NumPy数组一样,拒绝减少到一个布尔值 - they raise a ValueError instead。
要修复代码,可以使用
df['v2_flag'] = np.where( (df['v2']=='f') | (df['v2']=='h'), 1, 0)
|
在两个布尔值系列上执行按位或元素。
定义df['v2_flag']
的其他方式包括
df['v2_flag'] = ((df['v2']=='f') | (df['v2']=='h')).astype(int)
或
df['v2_flag'] = df['v2'].isin(['f', 'h']).astype(int)