pandas 中特定观察组的累积乘积

cumulative product for specific groups of observations in pandas

我有以下类型的数据集

           Date    ID  window        var
0    1998-01-28     X      -5  8.500e-03
1    1998-01-28     Y      -5  1.518e-02
2    1998-01-29     X      -4  8.005e-03
3    1998-01-29     Y      -4  7.905e-03
4    1998-01-30     X      -3 -5.497e-03
         ...   ...     ...        ...
3339 2016-12-19     Y       3 -4.365e-04
3340 2016-12-20     X       4  3.628e-03
3341 2016-12-20     Y       4  6.608e-03
3342 2016-12-21     X       5 -2.467e-03
3343 2016-12-21     Y       5 -2.651e-03

我的目的是根据变量window计算变量var的累加积。这个想法是,对于每个日期,我都确定了该日期前后 5 天的 window /变量 window 从 -5 到 5)。现在,我想计算属于特定日期的 window 中的累计乘积。例如,第一个日期 (1998-01-28) 的 windows 值为 -5,因此表示计算 cumprod 的起点。我想要一个名为 cumprod 的新变量,它正好是 varwindow 为 -5 的日期,那么它是 var 的值之间的 cumprod -5 和 -4,依此类推,直到 window 等于 5。这为第一组日期定义了 cumprod 的值,其中每组都是由连续日期定义的 var 从 -5 开始到 5 结束。然后我将对任何一组日期重复此操作。因此我会得到类似

的东西
           Date    ID  window        var   cumprod
0    1998-01-28     X      -5  8.500e-03 8.500e-03 
1    1998-01-28     Y      -5  1.518e-02 1.518e-02
2    1998-01-29     X      -4  8.005e-03 6.80425e-05
3    1998-01-29     Y      -4  7.905e-03 0.00011999790000000002
4    1998-01-30     X      -3 -5.497e-03
         ...   ...     ...        ...
3339 2016-12-19     Y       3 -4.365e-04
3340 2016-12-20     X       4  3.628e-03
3341 2016-12-20     Y       4  6.608e-03
3342 2016-12-21     X       5 -2.467e-03
3343 2016-12-21     Y       5 -2.651e-03

我在 cumprod 中给出了前两个日期的示例。

我怎样才能做到这一点?我在想找到一种方法将标识符附加到每组日期,然后 运行 使用 .groupby(group_identifier) 的某种 cumprod() 方法。我想不出该怎么做。是否可以通过在 window 上使用 rolling 函数来简化它?非常欢迎任何其他类型的方法。

我建议如下

import numpy as np
import pandas as pd
np.random.seed(123)
df = pd.DataFrame({"Date": pd.date_range("1998-01-28", freq="d", periods=22),
                   "window": np.concatenate([np.arange(-5,6,1),np.arange(-5,6,1)]),
                   "var": np.random.randint(1,10,22)
                   })

我的 df 与你的相似:

       Date  window  var
0  1998-01-28      -5    3
1  1998-01-29      -4    3
2  1998-01-30      -3    7
3  1998-01-31      -2    2
4  1998-02-01      -1    4
5  1998-02-02       0    7
6  1998-02-03       1    2
7  1998-02-04       2    1
8  1998-02-05       3    2
9  1998-02-06       4    1
10 1998-02-07       5    1
11 1998-02-08      -5    4
12 1998-02-09      -4    5

然后我创建一个分组变量并使用 cumprod:

转换 var
df =  df.sort_values("Date") # My df is already sorted by Date given the way 
# I created it, but I add this to make sure yours is sorted by date
df["group"] = (df["window"] == -5).cumsum()
df = pd.concat([df, df.groupby("group")["var"].transform("cumprod")], axis=1)

结果是:

        Date  window  var  group     var
0  1998-01-28      -5    3      1       3
1  1998-01-29      -4    3      1       9
2  1998-01-30      -3    7      1      63
3  1998-01-31      -2    2      1     126
4  1998-02-01      -1    4      1     504
5  1998-02-02       0    7      1    3528
6  1998-02-03       1    2      1    7056
7  1998-02-04       2    1      1    7056
8  1998-02-05       3    2      1   14112
9  1998-02-06       4    1      1   14112
10 1998-02-07       5    1      1   14112
11 1998-02-08      -5    4      2       4
12 1998-02-09      -4    5      2      20
13 1998-02-10      -3    1      2      20