从Python中的数据点中find移动平均数

我再次玩Python,并且find了一个带有例子的整洁的书。 其中一个例子是绘制一些数据。 我有一个两列的.txt文件,我有数据。 我绘制的数据很好,但在练习中说:进一步修改程序来计算和绘制数据的运行平均值,定义如下:

$Y_k=\frac{1}{2r}\sum_{m=-r}^r y_{k+m}$ 

在这种情况下r=5 (而y_k是数据文件中的第二列)。 让程序在同一个图上绘制原始数据和运行平均值。

到目前为止,我有这样的:

 from pylab import plot, ylim, xlim, show, xlabel, ylabel from numpy import linspace, loadtxt data = loadtxt("sunspots.txt", float) r=5.0 x = data[:,0] y = data[:,1] plot(x,y) xlim(0,1000) xlabel("Months since Jan 1749.") ylabel("No. of Sun spots") show() 

那么如何计算总和? 在Mathematica中它很简单,因为它是符号操作(例如Sum [i,{i,0,10})),但是如何在python中计算每一个十点的数据并对其求平均,直到结束点数?

我看了一下这本书,却发现什么都不能解释这个:


heltonbiker的代码做了诡计^^:D

 from __future__ import division from pylab import plot, ylim, xlim, show, xlabel, ylabel, grid from numpy import linspace, loadtxt, ones, convolve import numpy as numpy data = loadtxt("sunspots.txt", float) def movingaverage(interval, window_size): window= numpy.ones(int(window_size))/float(window_size) return numpy.convolve(interval, window, 'same') x = data[:,0] y = data[:,1] plot(x,y,"k.") y_av = movingaverage(y, 10) plot(x, y_av,"r") xlim(0,1000) xlabel("Months since Jan 1749.") ylabel("No. of Sun spots") grid(True) show() 

我得到这个:

图片

非常感谢你^^ 🙂

在阅读这个答案之前,请记住下面还有另外一个答案,Roman Kh使用了numpy.cumsum ,比这个更快。


最佳将一个移动/滑动平均值(或任何其他滑动窗口函数)应用于信号的一种常用方法是使用numpy.convolve()

 def movingaverage(interval, window_size): window = numpy.ones(int(window_size))/float(window_size) return numpy.convolve(interval, window, 'same') 

这里,interval是你的x数组,而window_size是要考虑的样本数。 窗口将以每个样本为中心,因此它会在当前样本前后采样,以便计算平均值。 你的代码将变成:

 plot(x,y) xlim(0,1000) x_av = movingaverage(interval, r) plot(x_av, y) xlabel("Months since Jan 1749.") ylabel("No. of Sun spots") show() 

希望这可以帮助!

由于numpy.convolve非常慢,那些需要快速执行的解决scheme的人可能更喜欢更容易理解的cumsum方法。 这里是代码:

 cumsum_vec = numpy.cumsum(numpy.insert(data, 0, 0)) ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width 

其中数据包含您的数据, ma_vec将包含移动的window_width长度的平均值。

cumsum的平均速度convolve快大约30-40倍。

移动平均值是一个卷积,numpy将比大多数纯Python操作更快。 这会给你10点的移动平均线。

 import numpy as np smoothed = np.convolve(data, np.ones(10)/10) 

如果您使用时间序列数据,我也强烈build议使用大pandas包。 有一些很好的移动平均操作内置 。

 ravgs = [sum(data[i:i+5])/5. for i in range(len(data)-4)] 

这不是最有效的方法,但它会给你的答案,我不清楚你的窗口是5点还是10点。如果是10点,则用10代替5,用9代替4。

接受的答案有问题。 我认为我们需要在这里使用“有效”而不是“相同”return numpy.convolve(interval, window, 'same')

作为一个例子,尝试这个数据集的MA = [1,5,7,2,6,7,8,2,2,7,8,3,7,3,7,3,15,6] – 结果应该是[4.2,5.4,6.0,5.0,5.0,5.2,5.4,4.4,5.4,5.6,5.6,4.6,7.0,6.8] ,但是“相同”给我们一个错误的输出[2.6,3.0,4.2,5.4,6.0,5.0,5.0,5.2,5.4,4.4,5.4,5.6,5.6, 4.6,7.0,6.8,6.2,4.8]

生锈的代码试试这个 – :

 result=[] dataset=[1,5,7,2,6,7,8,2,2,7,8,3,7,3,7,3,15,6] window_size=5 for index in xrange(len(dataset)): if index <=len(dataset)-window_size : tmp=(dataset[index]+ dataset[index+1]+ dataset[index+2]+ dataset[index+3]+ dataset[index+4])/5.0 result.append(tmp) else: pass result==movingaverage(y, window_size) 

试试这与有效&相同,看看math是否有道理。

另请参阅 – : http : //sentdex.com/sentiment-analysisbig-data-and-python-tutorials-algorithmic-trading/how-to-chart-stocks-and-forex-doing-your-own-financial-charting/计算-简单移动平均-SMA蟒/

我觉得像这样:

 aves = [sum(data[i:i+6]) for i in range(0, len(data), 5)] 

但我总是要仔细检查指数是否符合我的预期。 你想要的范围是(0,5,10,…)和数据[0:6]会给你数据[0] …数据[5]

ETA:哎呀,当然,你想要大概而不是总和。 所以实际上使用你的代码和公式:

 r = 5 x = data[:,0] y1 = data[:,1] y2 = [ave(y1[ir:i+r]) for i in range(r, len(y1), 2*r)] y = [y1, y2] 

我的移动平均function,没有numpyfunction:

 from __future__ import division # must be on first line of script class Solution: def Moving_Avg(self,A): m = A[0] B = [] B.append(m) for i in range(1,len(A)): m = (m * i + A[i])/(i+1) B.append(m) return B