Pandas - 每个日期有许多测量值的日期移动平均值

Pandas - moving average for date with many measurements per date

我有一个包含日期和销售额的 DataFrame。我想计算最近 5 天的移动平均值并将其分配给每一天。问题是我每天都有多次测量(准确地说是 1115 - 对于单次测量,我知道该怎么做)。

我的数据是这样的:

    Date        Sales
0   2013-01-01  0
1   2013-01-01  0
2   2013-01-01  0
3   2013-01-01  0
4   2013-01-01  0
... ... ...
1017204 2015-07-31  9082
1017205 2015-07-31  10708
1017206 2015-07-31  7481
1017207 2015-07-31  10460
1017208 2015-07-31  5263

我想首先计算过去 5 天的移动平均值(对过去 5 天的所有 1115 * 5 = 5575 次测量取平均值),然后将其分配回每个单独的测量值(每个测量值都应该有这个平均分配)。我的数据将如下所示:

    Date        Sales       Last5DaysAvg
0   2013-01-01  0   NaN
1   2013-01-01  0   NaN
2   2013-01-01  0   NaN
3   2013-01-01  0   NaN
4   2013-01-01  0   NaN
... ... ...
5576    2013-01-06  (average from 2013-01-01 to 2013-01-06)
5577    2013-01-06  (average from 2013-01-01 to 2013-01-06)
5578    2013-01-06  (average from 2013-01-01 to 2013-01-06)
...
1017204 2015-07-31  9082    (average from 2015-07-26 to 2015-07-31)
1017205 2015-07-31  10708   (average from 2015-07-26 to 2015-07-31)
1017206 2015-07-31  7481    (average from 2015-07-26 to 2015-07-31)
1017207 2015-07-31  10460   (average from 2015-07-26 to 2015-07-31)
1017208 2015-07-31  5263    (average from 2015-07-26 to 2015-07-31)

我尝试对初学者使用 .count() 聚合,因为它很容易验证 - 每行中应该 return 5575(除了前 5575 行,我当然会有NaNs):

df = df.rolling("5D", on="Date").count()

但我得到:

    Date        Sales
0   2013-01-01  1.0
1   2013-01-01  2.0
2   2013-01-01  3.0
3   2013-01-01  4.0
4   2013-01-01  5.0
... ... ...
1017204 2015-07-31  5571.0
1017205 2015-07-31  5572.0
1017206 2015-07-31  5573.0

所以看起来好像每天都分开,根本没有计算移动window。

问题:我怎样才能达到上面列出的结果?

数据:(前 30000 行)https://pastebin.com/5bQ4Zt3f

编辑: 我设法使它工作,但以一种非常丑陋的方式,我认为有更漂亮、更有效的方法。此外,下面的代码对每天的测量次数进行了硬编码,但无法始终保证这一点。

df = df.groupby([pd.Grouper(key="Date", freq="D")]) \
             .sum() \
             .reset_index() \
             .sort_values("Date")
df = df.rolling(5, on="Date").sum()
df["Sales"] = df["Sales"] / (1115 * 5)
Date    Sales
0   2013-01-01  NaN
1   2013-01-02  NaN
2   2013-01-03  NaN
3   2013-01-04  NaN
4   2013-01-05  4661.063857
... ... ...
937 2015-07-27  5435.554439
938 2015-07-28  5871.071031
939 2015-07-29  6211.633722
940 2015-07-30  6709.784036
941 2015-07-31  8471.914439

不清楚为什么每个日期都有多行。我看到 2 种可能的解释:

  • 这些是您必须在星形处聚合然后生成单个滚动平均值的值:
df.groupBy('Date').sum().rolling(5).mean().reset_index()
  • 或者这些是不同的产品 - 那么您仍然需要分组,但您可以计算每个产品的滚动平均值而不是聚合:
df.groupby('Product')['Date'].rolling(5).mean().reset_index()