Python 基于数据帧中其他两列值的条件选择的新列

Python 基于数据帧中其他两列值的条件选择的新列,python,pandas,python-3.3,Python,Pandas,Python 3.3,我有一个数据框,其中包含股票价值 看起来是这样的: >>>Data Open High Low Close Volume Adj Close Date 2013-07-08 76.91 77.81 76.85 77.04 5106200 77.04 当我尝试使用以下if语句创建条件新列时: Data['Test'] =Data['Close'] if Da

我有一个
数据框
,其中包含股票价值

看起来是这样的:

>>>Data Open High Low Close Volume Adj Close Date                                                       
2013-07-08  76.91  77.81  76.85  77.04  5106200  77.04
当我尝试使用以下if语句创建条件新列时:

Data['Test'] =Data['Close'] if Data['Close'] > Data['Open'] else Data['Open']
我得到以下错误:

Traceback (most recent call last):
  File "<pyshell#116>", line 1, in <module>
    Data[1]['Test'] =Data[1]['Close'] if Data[1]['Close'] > Data[1]['Open'] else Data[1]['Open']
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
结果是选择了整个
['Open']
列。我没有得到我想要的条件,即每次选择
['Open']
['Close']
列之间的最大值

感谢您的帮助


谢谢。

问题是,您要求python计算一个包含多个布尔值的条件(
Data['Close']>Data['Open']
)。您不想使用
any
all
,因为这会将
Data['Test']
设置为
Data['Open']
Data['Close']

可能有更干净的方法,但有一种方法是使用掩码(布尔数组):

这是一个where条件,表示如果a>B,给我a的值,否则给我B

# this syntax is EQUIVALENT to
# df.loc[df['A']>df['B'],'A'] = df['B']

In [9]: df['A'].where(df['A']>df['B'],df['B'])
Out[9]: 
0   -0.485977
1    0.364845
2    0.020029
3    0.778569
4    0.437513
5    0.362016
6    2.880953
7    0.624493
8    1.015952
9    1.843267
dtype: float64
在这种情况下,
max
是等效的

In [10]: df.max(1)
Out[10]: 
0   -0.485977
1    0.364845
2    0.020029
3    0.778569
4    0.437513
5    0.362016
6    2.880953
7    0.624493
8    1.015952
9    1.843267
dtype: float64
从数据帧,如:

>>> df
         Date   Open   High    Low  Close   Volume  Adj Close
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04
我能想到的最简单的事情是:

>>> df["Test"] = df[["Open", "Close"]].max(axis=1)
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23
df.ix[:,[“打开”,“关闭”]].max(axis=1)
可能会快一点,但我觉得它看起来没那么好看

或者,您可以对行使用
。应用

>>> df["Test"] = df.apply(lambda row: max(row["Open"], row["Close"]), axis=1)
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23
或者回到numpy:

>>> df["Test"] = np.maximum(df["Open"], df["Close"])
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23

基本问题是
if/else
不能很好地处理数组,因为
if(something)
总是将
something
强制为单个
bool
。它并不等同于“对于数组中的每个元素,如果条件成立的话”,或者类似的东西

在我有
df['B']
的地方,你可以放一个标量(例如“Close”),尽管你真的应该在另一列(例如,你从中选择的列,
df['a']
不必与掩码
df['a']>df['B']
相同,否则你会得到一个混合的浮点/字符串列,通常没有用(对任何事情都没有效率)。您也可以使用另一列,其中我有
df['B']
作为替换值(熊猫将其与选择器列对齐)。仅供参考,这完全等同于:
df.loc[df['A']>df['B'],'A']=df['B']
>>> df["Test"] = df[["Open", "Close"]].max(axis=1)
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23
>>> df["Test"] = df.apply(lambda row: max(row["Open"], row["Close"]), axis=1)
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23
>>> df["Test"] = np.maximum(df["Open"], df["Close"])
>>> df
         Date   Open   High    Low  Close   Volume  Adj Close   Test
0  2013-07-08  76.91  77.81  76.85  77.04  5106200      77.04  77.04
1  2013-07-00  77.04  79.81  71.81  72.87  1920834      77.04  77.04
2  2013-07-10  72.87  99.81  64.23  93.23  2934843      77.04  93.23