带有分组依据的尾随或移动平均线

Trailing or Moving Average with a Group By

我想在执行 groupby 时计算尾随或移动平均线。在下面的示例中,我展示了 5 天移动平均线。

我的数据类似于:

ID  Date         KG      Volume
1   8/10/2018    1,000   10 
1   8/11/2018    500     6 
1   8/12/2018    750     2 
1   8/13/2018    500     6 
1   8/13/2018    500     6 
1   8/14/2018    1,000   4 
2   8/1/2018     1304    8
2   8/2/2018     626     1
2   8/3/2018     955     3
2   8/8/2018     445     4
2   8/10/2018    1356    11
2   8/13/2018    524     7
2   8/14/2018    331     5

我想按 ID 和日期列分组,然后计算 KG/Volume 列的连续 5 天平均值(从今天开始,即 8/10-8/14)。我需要按 ID 和日期分组的原因是像 ID 1 这样的情况,其中日期 8/13/18 出现了两次。在此示例中,我希望 18 年 8 月 13 日的 ID 1 有一个 1,000 公斤的条目用于平均计算(而不是两个 500 的条目)。

预期的输出类似于:

ID  Avg_KG  Avg_Vol
1   850     7 
2   442.2   4.6

另请注意,ID 2 缺少平均计算所需的 5 天中的 2 天。 ID 2 缺失的两天在平均计算中应作为 0 计算在内。这就是为什么 ID 2 的 KG 平均值是 442.2 而不是 737 的原因。

我曾尝试使用 .rolling(5).mean(),但在将其与 groupby 语句结合使用时得到的结果不正确。

首先,一些设置:

df.Date = pd.to_datetime(df.Date)
df.KG = df.KG.str.replace(',', '').astype(int)

现在按 DateID 分组并对重复天数求和:

s = df.groupby(['Date', 'ID']).agg({'KG': 'sum', 'Volume': 'sum'}).reset_index(1)

            ID    KG  Volume
Date
2018-08-01   2  1304       8
2018-08-02   2   626       1
2018-08-03   2   955       3
2018-08-08   2   445       4
2018-08-10   1  1000      10
2018-08-10   2  1356      11
2018-08-11   1   500       6
2018-08-12   1   750       2
2018-08-13   1  1000      12
2018-08-13   2   524       7
2018-08-14   1  1000       4
2018-08-14   2   331       5

接下来,重新采样以占 "missing" 天:

out = s.groupby('ID').resample('1D').asfreq().drop('ID', 1).reset_index(0).fillna(0)

最后,索引你过去 5 天的 DataFrame,并使用 mean:

out.groupby('ID').tail(5).groupby('ID').mean()

        KG  Volume
ID
1.0  850.0     6.8
2.0  442.2     4.6