我有一个pandas DataFrame。如果x的先前值小于50且当前值大于50,我想为新列y添加值为1的新列。
我收到此错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
代码:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(40,60,size=(10, 1)), columns=['x'])
df['y'] = 1 if (df['x'].shift(1) < 50) and (df['x'] > 50) else 0
答案 0 :(得分:4)
这是一个古老的故事。 pandas为您提供了比特运算符的重载版本,您应该将其用于向量化OR / AND运算。无论如何,根据您的代码,astype
转换在这里更合适。
In [139]: df['y'] = ((df['x'].shift(1) < 50) & (df['x'] > 50)).astype(np.int8)
In [140]: df
Out[140]:
x y
0 51 0
1 51 0
2 48 0
3 54 1
4 47 0
5 41 0
6 51 1
7 49 0
8 53 1
9 41 0
或不太常见的选项:
In [146]: df.eval("(x.shift() < 50 and x > 50) * 1", inplace=False, engine='python')
Out[146]:
0 0
1 0
2 0
3 1
4 0
5 0
6 1
7 0
8 1
9 0
Name: x, dtype: int32
答案 1 :(得分:3)
and
是Python类可以不覆盖的运算符。它需要两个表达式作为输入。它评估第一个。如果第一个的真实性是True
,那么它会评估后者并返回该结果。如果质量为False
,则返回前一个表达式的结果。
这里可以使用的是布尔运算符&
(逻辑和)和|
(逻辑或)。我们可以将其重写为:
df['y'] = ((df['x'].shift(1) < 50) & (df['x'] > 50)).astype(int)
这里我们使用astype
将布尔行转换为一行整数。 False
映射到0
,True
映射到1
。