pandas根据两个条件设置列值

时间:2018-01-11 22:37:53

标签: python python-2.7 pandas

我有一个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

2 个答案:

答案 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映射到0True映射到1