如何快速在Pandas中计算单列的多滚动窗口均值
提速多窗口滚动均值计算的方法
针对600万行DataFrame计算窗口2到40的滚动均值,循环实现效率低下,以下是几种高效方案:
1. 利用前缀和(累积和)批量计算
滚动均值本质是窗口内元素的和除以窗口大小,通过计算一次累积和,可以快速推导所有窗口的结果,避免重复计算窗口内的和,这是效率提升最明显的方案。
代码示例:
import pandas as pd import numpy as np # 假设你的DataFrame是df,目标列为'col1' col_data = df['col1'].values cumsum = np.cumsum(col_data) # 补一个0在开头,方便计算前n项的和 cumsum = np.insert(cumsum, 0, 0) # 批量生成所有窗口的滚动均值 for window in range(2, 41): # 窗口和 = cumsum[window:] - cumsum[:-window] roll_sum = cumsum[window:] - cumsum[:-window] # 生成对应列,前面window-1个位置填充NaN roll_mean = np.concatenate([np.full(window-1, np.nan), roll_sum / window]) df[f'roll_{window}'] = roll_mean
此方法只需要计算一次累积和,后续所有窗口的均值都通过数组切片运算得到,时间复杂度从O(NK)(N为行数,K为窗口数)降至O(N+KN),实际运行速度比循环调用rolling().mean()快5-10倍以上。
2. 使用NumPy滑动窗口视图(内存充足时可选)
通过np.lib.stride_tricks.sliding_window_view生成所有可能的滑动窗口,再批量计算均值,适合内存足够的场景:
import numpy as np col_data = df['col1'].values # 生成最大窗口(40)的滑动窗口视图 window_view = np.lib.stride_tricks.sliding_window_view(col_data, window_shape=40) # 对每个子窗口计算不同长度的均值 for window in range(2, 41): # 取每个滑动窗口的前window个元素计算均值 mean_vals = window_view[:, :window].mean(axis=1) # 填充NaN并赋值给DataFrame df[f'roll_{window}'] = np.concatenate([np.full(window-1, np.nan), mean_vals])
注意:此方法会生成一个形状为(N-39, 40)的数组,600万行的话会占用约1.9GB内存(float64类型),如果内存不足,优先选择前缀和方案。
3. 禁用Pandas的链式赋值检查(有限提升)
如果你仍需要保留循环结构(不推荐),可以关闭Pandas的链式赋值检查,减少额外的开销:
pd.options.mode.chained_assignment = None # 关闭警告和检查 for i in range(2, 41): df[f'roll_{i}'] = df['col1'].rolling(i).mean() pd.options.mode.chained_assignment = 'warn' # 恢复默认
但此方法提升有限,远不如前缀和方案高效。
内容的提问来源于stack exchange,提问作者finman69
相关产品推荐
相关产品推荐

