我有每日级别的股票回报数据,如下所示:
df:
index ID Return
2016-01-04 A 0.01
2016-01-05 A 0.01
2016-01-06 A 0.02
...
2016-01-30 A 0.01
2016-02-02 A 0.05
...
2016-01-04 B 0.01
2016-01-05 B 0.01
...
我想为每个月内的每只股票创建一个累计回报列。此外,我希望每个月的第一个条目为1(换句话说,到日期的滞后累积回报),即:
df:
index ID Return Cum
2016-01-04 A 0.01 1
2016-01-05 A 0.02 1.01
2016-01-06 A 0.03 1.03
...
2016-01-30 A 0.01 1.31
2016-02-02 A 0.05 1
2016-02-03 A 0.01 1.05
...
2016-01-04 B 0.02 1
2016-01-05 B 0.01 1.02
到目前为止,我所做的是创建一个名为“ret_1”的列,即Return + 1,并使用cumprod和groupby:
df['ret_1'] = df['Return'] + 1
cum = df.groupby(['ID', pd.Grouper(freq='M')])['ret_1'].cumprod()
然而,这给出了CURRENT累积回报,而不是LAG累积回报。然后我用了:
new_df = cum.shift(1, 'D')
这适用于中间的日期,但是它并没有在每个月的开头添加“1”(实际上,它通过将整个索引向下移动1天完全删除了每个月的第一个条目)。它还为每个月末创建了一个“额外”日期,例如2016-01-31为库存A.
答案 0 :(得分:0)
IIUC
df['Cum']=df.groupby([df.ID,df.index.month]).Return.apply(lambda x : x.shift().fillna(0).add(1).cumprod()).values
df
Out[213]:
ID Return Cum
index
2016-01-04 A 0.01 1.00
2016-01-05 A 0.01 1.01
2016-01-06 A 0.02 1.02
2016-01-30 A 0.01 1.04
2016-02-02 A 0.05 1.00
2016-01-04 B 0.01 1.00
2016-01-05 B 0.01 1.01