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()
我有一个包含日期和销售额的 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()