我已经用支持这种结构的批处理转换语言定义了大量的数据转换:x = iif(condition,a,b)。我想使用数据框重写这些。
我正在使用Dataframe.assign(),但得到ValueError:系列的真值不明确。使用a.empty,a.bool(),a.item(),a.any()或a.all()。
import pandas as pd
df = pd.DataFrame(['apple', 'orange', 'granite'], columns=['name'])
df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-39-e9ad71ccc45b> in <module>()
----> 1 df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')
~\Anaconda3\lib\site-packages\pandas\core\frame.py in assign(self, **kwargs)
3305 if PY36:
3306 for k, v in kwargs.items():
-> 3307 data[k] = com._apply_if_callable(v, data)
3308 else:
3309 # <= 3.5: do all calculations first...
~\Anaconda3\lib\site-packages\pandas\core\common.py in _apply_if_callable(maybe_callable, obj, **kwargs)
403
404 if callable(maybe_callable):
--> 405 return maybe_callable(obj, **kwargs)
406
407 return maybe_callable
<ipython-input-39-e9ad71ccc45b> in <lambda>(x)
----> 1 df.assign(taste = lambda x: 'rocky' if (x.name=='granite') else 'yummy')
~\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
1571 raise ValueError("The truth value of a {0} is ambiguous. "
1572 "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1573 .format(self.__class__.__name__))
1574
1575 __bool__ = __nonzero__
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
起初我以为这是由于对assign()中所允许的关键字的限制,但是非常相似的构造适用于apply():
df['name'].apply(lambda x: 'rocky' if (x=='granite') else 'yummy')
0 yummy
1 yummy
2 rocky
Name: name, dtype: object
但是,这不允许我使用if条件,该条件使用数据框中的多个列。有没有一种方法可以让Assign()工作?
答案 0 :(得分:2)
分配不是您应在条件分配中使用的功能
df['taste']=np.where(df['name'].eq('granite'),'rocky','yummy')
df
Out[513]:
name taste
0 apple yummy
1 orange yummy
2 granite rocky
答案 1 :(得分:2)
调用Series.apply
时,lambda接收每个行值(即标量值)。使用assign
,lambda接收整个DataFrame。了解这一点意味着您现在可以执行
df.assign(taste=lambda x: np.where(x['name'] == 'granite', 'r', 'y'))
name taste
0 apple y
1 orange y
2 granite r
或者,
df.assign(taste=np.where(df['name'] == 'granite', 'r', 'y'))
name taste
0 apple y
1 orange y
2 granite r
或者,更简单地说,是就地分配,
df['taste'] = np.where(df['name'] == 'granite', 'r', 'y')
df
name taste
0 apple y
1 orange y
2 granite r