似乎没有函数可以简单地计算 numpy/scipy 上的移动平均值,从而导致 复杂的解决方案。
我的问题有两个:
- (正确)使用 numpy 实现移动平均线的最简单方法是什么?
- 既然这看起来不简单且容易出错,那么是否有充分的理由不将 电池包含 在这种情况下?
原文由 loopbackbee 发布,翻译遵循 CC BY-SA 4.0 许可协议
似乎没有函数可以简单地计算 numpy/scipy 上的移动平均值,从而导致 复杂的解决方案。
我的问题有两个:
原文由 loopbackbee 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果您只想要一个简单的非加权移动平均线,您可以使用 np.cumsum
轻松实现它,这可能 比 基于 FFT 的方法更快:
编辑 更正了 Bean 在代码中发现的一个错误索引。 编辑
def moving_average(a, n=3) :
ret = np.cumsum(a, dtype=float)
ret[n:] = ret[n:] - ret[:-n]
return ret[n - 1:] / n
>>> a = np.arange(20)
>>> moving_average(a)
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.,
12., 13., 14., 15., 16., 17., 18.])
>>> moving_average(a, n=4)
array([ 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5,
10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5])
所以我猜答案是:它真的很容易实现,也许 numpy 已经有点臃肿的专门功能。
原文由 Jaime 发布,翻译遵循 CC BY-SA 3.0 许可协议
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
1 回答3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.5k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
实现此目的的一种简单方法是使用
np.convolve
。这背后的想法是利用计算 离散卷积 的方式并使用它来返回 _滚动平均值_。这可以通过与长度等于我们想要的滑动窗口长度的np.ones
序列进行卷积来完成。为此,我们可以定义以下函数:
此函数将采用序列
x
和长度为w
的序列的卷积。请注意,选择的mode
是valid
以便仅对序列完全重叠的点给出卷积乘积。一些例子:
对于长度为
2
的窗口的移动平均线,我们将有:对于长度为
4
的窗口:convolve
是如何工作的?让我们更深入地了解计算离散卷积的方式。以下函数旨在复制
np.convolve
计算输出值的方式:对于上面的相同示例,这也会产生:
因此,每一步所做的就是在数组和当前 窗口 之间取内积。在这种情况下,乘以
np.ones(w)
是多余的,因为我们直接取序列的sum
。Bellow 是如何计算第一个输出的示例,以便更清晰一些。假设我们想要一个
w=4
的窗口:以下输出将计算为:
依此类推,一旦执行了所有重叠,就返回序列的移动平均值。