Search code examples
pandasrolling-computation

python rolling product on non-adjacent row


I would like to calculate rolling product of non-adjacent row, such as product of values in every fifth row as shown in the photo (result in blue cell is the product of data in blue cell etc.)

enter image description here

The best way I can do now is the following;

temp = pd.DataFrame([range(20)]).transpose()
df = temp.copy()
df['shift1'] = temp.shift(5)
df['shift2'] = temp.shift(10)
df['shift3'] = temp.shift(15)

result = df.product(axis=1)

however, it looks to be cumbersome as I want to change the row step dynamically. can anyone tell me if there is a better way to navigate this? Thank you


Solution

  • You can use groupby.cumprod/groupby.prod with the modulo 5 as grouper:

    import numpy as np
    m = np.arange(len(df)) % 5
    
    # option 1
    df['result'] = df.groupby(m)['data'].cumprod()
    
    # option 2
    df.loc[~m.duplicated(keep='last'), 'result2'] = df.groupby(m)['data'].cumprod()
    # or
    # df.loc[~m.duplicated(keep='last'),
    #        'result2'] = df.groupby(m)['data'].prod().to_numpy()
    

    output:

        data  result  result2
    0      0       0      NaN
    1      1       1      NaN
    2      2       2      NaN
    3      3       3      NaN
    4      4       4      NaN
    5      5       0      NaN
    6      6       6      NaN
    7      7      14      NaN
    8      8      24      NaN
    9      9      36      NaN
    10    10       0      NaN
    11    11      66      NaN
    12    12     168      NaN
    13    13     312      NaN
    14    14     504      NaN
    15    15       0      0.0
    16    16    1056   1056.0
    17    17    2856   2856.0
    18    18    5616   5616.0
    19    19    9576   9576.0