Python 熊猫-日期的移动平均值,每个日期有多个测量值

Python 熊猫-日期的移动平均值,每个日期有多个测量值,python,pandas,dataframe,date,rolling-computation,Python,Pandas,Dataframe,Date,Rolling Computation,我有一个带有日期和销售额的数据框。我想计算过去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 101720

我有一个带有日期和销售额的数据框。我想计算过去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
    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)
首先计算过去5天的移动平均值(取过去5天所有1115*5=5575次测量值的平均值),然后将其分配回每个单独测量值(每个测量值应分配此平均值)。我的数据将如下所示:

    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
    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()
聚合,因为它很容易验证-每行应该返回5575(除了前5575行,我当然会有NAN):

但我得到:

    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
所以它看起来每天都是分开的,根本没有计算移动窗口

问题:我如何实现上述结果

数据:(前30000行)

编辑:我设法让它工作起来,但在相当丑陋的方面,我认为有更漂亮、更有效的方法。此外,下面的代码对每天的测量次数进行了硬编码,这是无法保证的

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)

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

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

很抱歉,我不太了解“产品”栏的内容-我没有它(只有索引、日期和销售),我该怎么办?该索引已经是默认索引,因此reset_index()实际上不起任何作用。编辑后,如果需要进一步澄清,请告诉我-我有1115家店铺,因此每天1115个销售值,所以我只需要1个滚动平均值(它代表数据中的趋势)。因此,我希望避免使用groupby()计算每天的总和/平均值。相反,我认为更合适的做法是从过去5天的数据中(从所有存储中,因此1115*5个值)直接计算平均值。我不确定通过避免初始聚合是否会获得任何好处-这降低了所有后续操作的复杂性。但是你可以简单地按
1115*5
行滚动,然后为每个日期选择第一个值,即
df.rolling(1115*5).mean().groupby('date').first().reset_index()
你可能是对的,我可能想得太多了。谢谢你的帮助!