I have a dataframe as follows
id | return1 | return2 |
---|---|---|
weekday1 | 0.1 | 0.2 |
weekday1 | 0.2 | 0.4 |
weekday1 | 0.3 | 0.5 |
weekday2 | 0.4 | 0.7 |
weekday2 | 0.5 | 0.6 |
weekday2 | 0.6 | 0.1 |
I know how to do the rolling-groupby-sum, which is
df.groupby(df.index.dayofweek) #originally the index is a time series
.rolling(52).sum()
.droplevel(level=0).sort_index()
Now I need to add 1 to all the elements first and then multiply those in the same group as follows.
Step 1 - add 1:
id | return1 | return2 |
---|---|---|
weekday1 | 1.1 | 1.2 |
weekday1 | 1.2 | 1.4 |
weekday1 | 1.3 | 1.5 |
weekday2 | 1.4 | 1.7 |
weekday2 | 1.5 | 1.6 |
weekday2 | 1.6 | 1.1 |
Step2 - multiply by group:
id | return1 | return2 |
---|---|---|
weekday1 | 1.1×1.2×1.3 | 1.2×1.4×1.5 |
weekday2 | 1.4×1.5×1.6 | 1.7×1.6×1.1 |
I use the following codes
df.transform(lambda x : x 1).groupby(df.index.dayofweek)
.rolling(52).mul()
.droplevel(level=0).sort_index()
but it gives an AttributeError: 'RollingGroupby' object has no attribute 'mul'.
cumprod() doesn't work either. Perhaps it has somthing to do with the rolling part for that there's no such thing as rolling.cumprod() or rolling.mul().
Is there a better way to do the multiplication within a group with rolling part?
CodePudding user response:
Use numpy.prod
in Rolling.apply
:
df.add(1).groupby(df.index.dayofweek).rolling(52).apply(np.prod)
Btw, from expected ouput seems need GroupBy.prod
:
df.add(1).groupby(df.index).prod()