先前计算的移动平均线的移动平均线

moving average on previous calculated moving average

我有如下数据框:

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 天的移动平均值 (window size = 2) 并将该值放入新列中(假设 'MA'),但问题是我希望这个 window 滚动实际销售和之前计算的 MA。下图是解释:

抱歉,我不得不用图片阐明我的问题:|

我知道我必须按商店分组,我可以使用 rolling(2),但该方法只会计算一列的移动平均值。

我原来的window是15,上面只是举例

如有任何帮助,我们将不胜感激。

如果不为该问题编写自定义代码,我想不出解决此问题的方法,因为您正在使用之前生成的数据。下面的片段是我想出的。它以线性时间运行,我相信这是你能得到的最好的,主要是就地运行,只需要额外存储 pd.Series 长度 window,进行最少的复制,只查看每个值一次它可以与任意 window 大小一起使用,从而可以直接扩展到您的实际用例

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 Store 列和 apply 函数就像这样:

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

如果您最终在大量真实数据上使用它,我很想听听它在运行时方面的表现。干杯