
本文介绍如何高效地对形状为 (n, 3) 的二维数组沿行方向(即按每连续3行)计算滚动均值,输出一维结果数组,全程避免显式循环,利用 numpy 的卷积操作实现向量化加速。
本文介绍如何高效地对形状为 (n, 3) 的二维数组沿行方向(即按每连续3行)计算滚动均值,输出一维结果数组,全程避免显式循环,利用 numpy 的卷积操作实现向量化加速。
在科学计算和信号处理中,常需对数组沿某一维度进行滑动窗口统计(如滚动均值)。对于一个形状为 (6000, 3) 的二维数组 x,若希望对每连续3行(即窗口大小为 3,沿 axis=0 方向滑动)计算均值,并将每组 3 行 × 3 列的子数组压缩为一个标量(例如先按行求均值再对窗口求均值),最终得到长度为 6000 − 3 + 1 = 5998 的一维结果数组,推荐采用「降维 + 卷积」的两步向量化策略:
-
先行聚合:沿列方向(
axis=1)对每行求均值,将(6000, 3)压缩为(6000,)的一维数组row_means = np.mean(x, axis=1); -
再滑动平均:对该一维数组应用长度为 3 的均匀卷积核
np.ones(3)/3,使用mode='valid'模式——这等价于对每个长度为 3 的连续子数组求均值,输出长度为len(row_means) − 3 + 1 = 5998。
完整代码如下:
import numpy as np # 示例数据:(6000, 3) 数组 x = np.random.rand(6000, 3) # 向量化滚动均值(窗口大小=3,沿行方向) row_means = np.mean(x, axis=1) # shape: (6000,) out = np.convolve(row_means, np.ones(3)/3, mode='valid') # shape: (5998,) print(out.shape) # → (5998,)
✅ 优势说明:
- 完全避免 Python 循环,底层调用高度优化的 C 实现;
- 时间复杂度 O(N),远优于手动嵌套循环的 O(N×k);
-
np.convolve在'valid'模式下自动处理边界,无需额外裁剪。
⚠️ 注意事项:
- 此方法隐含假设:你希望的是「先对每行取均值,再对行均值序列做 3 点滑动平均」。若实际需求是「对每个
(3, 3)子矩阵(即 3 行 × 3 列)直接计算标量均值」,结果等价(因均值具有线性可加性:mean(x[i:i+3]) == mean(mean(x[i:i+3], axis=1))); - 若窗口大小
k变化,只需替换np.ones(k)/k和调整mode; - 对于更高维或跨多轴滚动操作,可考虑
scipy.ndimage.uniform_filter1d或numpy.lib.stride_tricks.sliding_window_view(NumPy ≥ 1.20),但本例中convolve最简洁高效。
综上,该方案以最少代码、最高性能达成目标,在处理大规模时间序列、传感器阵列或多通道数据时尤为实用。










