移动的滚动平均值 window
rolling mean with a moving window
我的数据框有一个每日价格列和一个 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
我想使用 window 列的 window 计算每行价格的滚动平均值。
结果是这样的:
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 的每一行...
就原始速度和复杂性而言,最佳解决方案基于 summed-area table 的想法。这个问题可以看作是一维的table。您可以在下面找到几种方法,从好到坏排列。
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
循环 + 线性复杂度
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'])]
循环 + 二次复杂度
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()
(reasons described ) 的这种方法,但如果您坚持使用,这里有一个解决方案:
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
我的数据框有一个每日价格列和一个 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
我想使用 window 列的 window 计算每行价格的滚动平均值。
结果是这样的:
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 的每一行...
就原始速度和复杂性而言,最佳解决方案基于 summed-area table 的想法。这个问题可以看作是一维的table。您可以在下面找到几种方法,从好到坏排列。
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
循环 + 线性复杂度
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'])]
循环 + 二次复杂度
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()
(reasons described
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