我有一个分钟股票收益率的数据框,我想创建一个新列,该列取决于是否超过了收益率(正负),如果是,则该行等于限制(正负) ,否则等于已检查的最后一列。下面的示例说明了这一点:
import pandas as pd
dict = [
{'ticker':'jpm','date': '2016-11-28','returns1': 0.02,'returns2': 0.03,'limit': 0.1},
{ 'ticker':'ge','date': '2016-11-28','returns1': 0.2,'returns2': -0.3,'limit': 0.1},
{'ticker':'fb', 'date': '2016-11-28','returns1': -0.2,'returns2': 0.5,'limit': 0.1},
]
df = pd.DataFrame(dict)
df['date'] = pd.to_datetime(df['date'])
df=df.set_index(['date','ticker'], drop=True)
目标将是这样:
fin_return limit returns1 returns2
date ticker
2016-11-28 jpm 0.03 0.1 0.02 0.03
ge 0.10 0.1 0.20 -0.30
fb -0.10 0.1 -0.20 0.50
因此,在第一行中,收益率从未超过限制,因此该值等于收益率2(0.03)中的值。在第2行中,收益超过了上行,因此该值应为正极限。在第3行中,收益率首先在下行方向超出,因此该值应为负极限。
我的实际数据帧有几千列,所以我不太确定如何执行此操作(可能是循环?)。我感谢任何建议。
该想法是测试止损或限价交易算法。无论何时触发下限,它都应将下一行替换为下限,上限也是如此,以该行中的先行者为准。因此,一旦触发了任何一个,就应该测试下一行。
我要添加一个示例,在此处再增加一列,以使其更加清晰(限制为+/- 0.1)
fin_return limit returns1 returns2 returns3
date ticker
2016-11-28 jpm 0.02 0.1 0.01 0.04 0.02
ge 0.10 0.1 0.20 -0.30 0.6
fb -0.10 0.1 -0.02 -0.20 0.7
在第一行中,从未触发过限制,直到最终收益是来自returns3(0.02)。在第2行中,限制在返回值1的上方触发,因此fin_return等于上限(在该行中,在returns2和return 3中发生的任何事情都不相关)。在第3行中,返回2的下行超出了限制,因此fin_return变为-0.1,而return3中的任何内容都不相关。
答案 0 :(得分:2)
使用:
dict = [
{'ticker':'jpm','date': '2016-11-28','returns1': 0.02,'returns2': 0.03,'limit': 0.1,'returns3':0.02},
{ 'ticker':'ge','date': '2016-11-28','returns1': 0.2,'returns2': -0.3,'limit': 0.1,'returns3':0.6},
{'ticker':'fb', 'date': '2016-11-28','returns1': -0.02,'returns2': -0.2,'limit': 0.1,'returns3':0.7},
]
df = pd.DataFrame(dict)
df['date'] = pd.to_datetime(df['date'])
df=df.set_index(['date','ticker'], drop=True)
#select all columns without first (here limit column)
df1 = df.iloc[:, 1:]
#comapre if all columns under +-limit
mask = df1.lt(df['limit'], axis=0) & df1.gt(-df['limit'], axis=0)
m1 = mask.all(axis=1)
print (m1)
date ticker
2016-11-28 jpm True
ge False
fb False
dtype: bool
#replace first columns in limit with NaNs and back filling missing values, seelct first col
m2 = df1.mask(mask).bfill(axis=1).iloc[:, 0].gt(df['limit'])
print (m2)
date ticker
2016-11-28 jpm False
ge True
fb False
dtype: bool
arr = np.select([m1,m2, ~m2], [df1.iloc[:, -1], df['limit'], -df['limit']])
#set first column in DataFrame by insert
df.insert(0, 'fin_return', arr)
print (df)
fin_return limit returns1 returns2 returns3
date ticker
2016-11-28 jpm 0.02 0.1 0.02 0.03 0.02
ge 0.10 0.1 0.20 -0.30 0.60
fb -0.10 0.1 -0.02 -0.20 0.70