Python 熊猫-日期的移动平均值,每个日期有多个测量值
我有一个带有日期和销售额的数据框。我想计算过去5天的移动平均值,并将其分配给每一天。问题是我每天都有多个测量值(精确到1115——对于单个测量值,我知道如何做到这一点) 我的数据如下所示: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
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()
你可能是对的,我可能想得太多了。谢谢你的帮助!