2013-04-11 81 views
6

如果满足某些条件,我想在当前存储在第(row + 1)行中的第二天的开放价格中提取价格并将其存储在新列中。大熊猫在数据框中的列表理解

df['b']='' 

df['shift']='' 

df['shift']=df['open'].shift(-1) 

df['b']=df[x for x in df['shift'] if df["MA10"]>df["MA100"]] 
+1

如果您想使用列表解析的结果作为指标,你应该使用:'DF [[对于df ['shift']中的x,如果df [“MA10”]> df [“MA100”]]]',但我认为这会引发一些异常。请张贴您的样本数据和期望的结果。 – HYRY 2013-04-11 05:28:44

+0

@HYRY感谢您的评论。我发布了一个链接到我的示例数据。我在发布之前使用了您的建议,并收到了错误“无效的语法”,正如我所提到的。 – 2013-04-11 11:28:30

+0

@ user1374969:计算HYRY建议中括号的数量,然后计算你的数量。 – DSM 2013-04-11 11:36:32

回答

8

有几种方法。使用apply

>>> df = pd.read_csv("bondstack.csv") 
>>> df["shift"] = df["open"].shift(-1) 
>>> df["b"] = df.apply(lambda row: row["shift"] if row["MA10"] > row["MA100"] else np.nan, axis=1) 

产生

>>> df[["MA10", "MA100", "shift", "b"]][:10] 
     MA10  MA100  shift   b 
0 16.915625 17.405625 16.734375  NaN 
1 16.871875 17.358750 17.171875  NaN 
2 16.893750 17.317187 17.359375  NaN 
3 16.950000 17.279062 17.359375  NaN 
4 17.137500 17.254062 18.640625  NaN 
5 17.365625 17.229063 18.921875 18.921875 
6 17.550000 17.200312 18.296875 18.296875 
7 17.681250 17.177500 18.640625 18.640625 
8 17.812500 17.159375 18.609375 18.609375 
9 17.943750 17.142813 18.234375 18.234375 

对于更量化的方法,你可以使用

>>> df = pd.read_csv("bondstack.csv") 
>>> df["b"] = np.nan 
>>> df["b"][df["MA10"] > df["MA100"]] = df["open"].shift(-1) 

或我的首选方法:

>>> df = pd.read_csv("bondstack.csv") 
>>> df["b"] = df["open"].shift(-1).where(df["MA10"] > df["MA100"]) 
+1

不能告诉你我有多少赞赏(在这个网站上)你的深思熟虑的建议和多种查看同一问题的方式。谢谢。 – 2013-04-11 12:18:44

+0

对于方法#3,我得到的时间序列对象没有属性'where'给出,其中是一个numpy属性,我用np.where()具有相同的错误。你有什么想法吗? – 2013-04-11 13:16:12

+0

您使用的是哪个版本的'pandas'?我使用0.10.1,上面的代码对你的数据工作得很好。 – DSM 2013-04-11 13:35:31

0

修改DSM的方法3,说明在np.where明确真/假值:

#numpy.where(condition, x, y) 
df["b"] = np.where(df["MA10"] > df["MA100"], df["open"].shift(-1), np.nan) 

使用明确列表理解:

#[xv if c else yv for (c,xv,yv) in zip(condition,x,y)]  #np.where documentation 
df['b'] = [ xv if c else np.nan for (c,xv) in zip(df["MA10"]> df["MA100"], df["open"].shift(-1))]