groupby累积和初始值

时间:2018-02-20 02:34:28

标签: python pandas dataframe group-by cumsum

我有每日级别的股票回报数据,如下所示:

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.

1 个答案:

答案 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