如何使用NumPy来计算移动平均线?

似乎没有任何function简单地计算numpy / scipy上的移动平均值,导致了复杂的解决scheme 。

我的问题是双重的:

  • (正确)用numpy实现移动平均线的最简单方法是什么?
  • 由于这似乎不平凡和容易出错,是否有一个很好的理由不包括在这种情况下的电池 ?

如果你只是想要一个简单的非加权移动平均数,你可以很容易地用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已经有点臃肿与专门的function。

NumPy缺乏特定的领域特定function可能是由于核心团队的纪律和NumPy的主要指令的保真度: 提供N维数组types ,以及创build和索引这些数组的function。 像许多基本目标一样,这个不算小,NumPy也不错。

(大得多) SciPy包含一个更大的特定于领域的库(被SciPy开发者称为子包 )的集合,例如数值优化( 优化 ),信号处理( 信号 )和积分( 积分 )。

我的猜测是,你所追求的function至less在SciPy子包之一( scipy.signal也许)中; 然而,我会首先看看SciPy scikits的集合,找出相关的scikit(s)并在那里寻找感兴趣的function。

Scikits是基于NumPy / SciPy的独立开发的软件包,针对特定的技术学科(例如, scikits-imagescikits-learn等)。其中有几个(尤其是用于数值优化的令人敬畏的OpenOpt )很久以前成熟的项目就select在相对较新的scikits rubric之下居住。 Scikits主页上面列出了大约30个这样的scikits ,但是其中至less有几个不再处于积极的发展状态。

遵循这个build议会导致你玩scikits-timeseries ; 但是,这一套scheme已经不再积极发展, 实际上, Pandas已经成为AFAIK 事实上的 NumPy时间序列库。

pandas有几个function可以用来计算移动平均数 ; 其中最简单的就是rolling_mean ,你可以这样使用:

 >>> # the recommended syntax to import pandas >>> import pandas as PD >>> import numpy as NP >>> # prepare some fake data: >>> # the date-time indices: >>> t = PD.date_range('1/1/2010', '12/31/2012', freq='D') >>> # the data: >>> x = NP.arange(0, t.shape[0]) >>> # combine the data & index into a Pandas 'Series' object >>> D = PD.Series(x, t) 

现在,只需调用传递Series对象的函数rolling_mean和一个窗口大小 ,在下面的例子中是10天

 >>> d_mva = PD.rolling_mean(D, 10) >>> # d_mva is the same size as the original Series >>> d_mva.shape (1096,) >>> # though obviously the first w values are NaN where w is the window size >>> d_mva[:3] 2010-01-01 NaN 2010-01-02 NaN 2010-01-03 NaN 

validation它是否奏效 – 例如,比较原始序列中的值10 – 15与使用滚动平均值进行平滑的新系列

 >>> D[10:15] 2010-01-11 2.041076 2010-01-12 2.041076 2010-01-13 2.720585 2010-01-14 2.720585 2010-01-15 3.656987 Freq: D >>> d_mva[10:20] 2010-01-11 3.131125 2010-01-12 3.035232 2010-01-13 2.923144 2010-01-14 2.811055 2010-01-15 2.785824 Freq: D 

函数rolling_mean,以及大约十几个其他函数都在Pandas文档中按照标题移动窗口函数非正式地分组; pandas中的第二个相关function组被称为指数加权函数(例如ewma ,其计算指数移动的加权平均值)。 第二组不包括在第一组( 移动窗口函数)的事实可能是因为指数加权变换不依赖于固定长度的窗口