我有一个如下数据框:
data = pd.DataFrame({'Date':['20191001','20191002','20191003','20191004','20191005','20191006','20191001','20191002','20191003','20191004','20191005','20191006'],'Store':['A','A','A','A','A','A','B','B','B','B','B','B'],'Sale':[1,2,8,6,9,0,4,3,0,2,3,7]})
我要做的是计算前2天(窗口大小= 2)每家商店的移动平均值,然后将该值放在新列中(假设为“ MA”),但是问题是我想要这个窗口会滚动显示实际销售和先前计算的MA。下图是说明:
对不起,我不得不用图片表达问题:|
我知道我必须按存储分组,并且可以使用rolling(2),但是该方法只能计算一列的移动平均值。
我的原始窗口是15,以上只是示例。
我们非常感谢您的帮助。
答案 0 :(得分:1)
由于您使用的是之前生成的数据,因此我无法完全想到一种无需编写自定义代码即可解决此问题的方法。下面的代码段是我想到的。它以线性时间运行,我相信它会尽力而为,主要是就地运行,只需要一个pd额外的存储空间即可。长度为def fill_ma(sales: pd.Series, window: int):
# "manually" do the first steps on the sales data
iter_data = sales.iloc[0:window]
for i in range(window):
iter_data.iloc[i] = np.mean(iter_data)
sales.iloc[0:window] = np.nan
sales.iloc[window:(2 * window)] = iter_data.values
# loop over the rest of the Series and compute the moving average of MA data
for i in range(2 * window, sales.shape[0]):
tmp = np.mean(iter_data)
iter_data.iloc[i % window] = tmp
sales.iloc[i] = tmp
return sales
的系列进行的复制很少,仅查看每个值一次,可以与任意窗口大小一起使用,从而可以直接扩展到您的实际用例
groupby
使用此功能非常简单:apply
的Store列和window = 2
data.groupby('Store')['Sale'].apply(lambda x: fill_ma(x, window))
0 NaN
1 NaN
2 1.5000
3 1.7500
4 1.6250
5 1.6875
6 NaN
7 NaN
8 3.5000
9 3.2500
10 3.3750
11 3.3125
Name: Sale, dtype: float64
的功能就像这样:
{{1}}
如果最终在大量真实数据上使用它,我很想听听它在运行时方面的表现。干杯