繁体   English   中英

带有移动窗口的滚动均值

[英]rolling mean with a moving window

我的数据框有一个每日价格列和一个窗口大小列:

df = pd.DataFrame(columns = ['price', 'window'],
             data = [[100, 1],[120, 2], [115, 2], [116, 2], [100, 4]])

df

        price   window
0        100    1
1        120    2
2        115    2
3        116    2
4        100    4

我想使用窗口列的窗口计算每行的价格滚动平均值。

结果是这样的:

df
    price   window  rolling_mean_price
0   100        1    100.00
1   120        2    110.00
2   115        2    117.50
3   116        2    115.50
4   100        4    112.75

我没有找到任何优雅的方法来使用 apply 并且我拒绝遍历我的 DataFrame 的每一行......

就原始速度和复杂性而言,最佳解决方案基于求和表中的想法。 这个问题可以看成是一张一维的表格。 您可以在下面找到几种方法,按照从最好到最差的顺序排列。

Numpy + 线性复杂度

size = len(df['price'])
price = np.zeros(size + 1)
price[1:] = df['price'].values.cumsum()

window = np.clip(np.arange(size) - (df['window'].values - 1), 0, None)
df['rolling_mean_price'] = (price[1:] - price[window]) / df['window'].values

print(df)

输出

   price  window  rolling_mean_price
0    100       1              100.00
1    120       2              110.00
2    115       2              117.50
3    116       2              115.50
4    100       4              112.75

Loopy + 线性复杂度

price = df['price'].values.cumsum()
df['rolling_mean_price'] = [(price[i] - float((i - w) > -1) * price[i-w]) / w for i, w in enumerate(df['window'])]

Loopy + 二次复杂度

price = df['price'].values
df['rolling_mean_price'] = [price[i - (w - 1):i + 1].mean() for i, w in enumerate(df['window'])]

我不会推荐使用pandas.DataFrame.apply()这种方法(原因在此处描述),但如果您坚持使用,这里有一个解决方案:

df['rolling_mean_price'] = df.apply(
    lambda row: df.rolling(row.window).price.mean().iloc[row.name], axis=1)

输出如下所示:

>>> print(df)
   price  window  rolling_mean_price
0    100       1              100.00
1    120       2              110.00
2    115       2              117.50
3    116       2              115.50
4    100       4              112.75

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM