groupby 累积总和初始值

groupby cumulative sum initial values

我有每日水平库存 return 数据如下:

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
...

我想为每个月的每只股票创建一列累计 return。此外,我希望每个月的第一个条目为 1(换句话说,滞后累计 return 到日期),即:

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 累积 return,而不是 LAG 累积 return。然后我使用了:

new_df = cum.shift(1, 'D')

这适用于中间的日期,但它不会在每个月的开头放置一个“1”(事实上,它通过将整个索引向下移动完全删除每个月的第一个条目1天)。它还会在每个月的末尾创建一个 "extra" 日期,例如股票 A 为 2016-01-31。

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