从Python中的数据点查找移动平均值

时间:2012-07-05 20:24:26

标签: python plot sum average

我再次使用Python,我找到了一本带有例子的简洁书籍。其中一个例子是绘制一些数据。我有一个包含两列的.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中的sum,它取数据中的每十个点并对其进行平均,直到结束分数?

我看了看这本书,但没有发现可以解释这一点:\


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()

我得到了这个:

image

非常感谢^^:)

6 个答案:

答案 0 :(得分:74)

  

在阅读这个答案之前,请记住下面还有另一个答案,来自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()

希望这有帮助!

答案 1 :(得分:25)

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

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

如果您正在处理时间序列数据,我也会强烈建议使用大熊猫包。有一些不错的moving average operations built in

答案 2 :(得分:4)

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

这不是最有效的方法,但它会给出你的答案,我不清楚你的窗口是5分还是10分。如果是10分,则将每个5替换为10,将4替换为9。

答案 3 :(得分: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) 

尝试使用有效的&amp;同样,看看数学是否有意义。

另见 - :http://sentdex.com/sentiment-analysisbig-data-and-python-tutorials-algorithmic-trading/how-to-chart-stocks-and-forex-doing-your-own-financial-charting/calculate-simple-moving-average-sma-python/

答案 4 :(得分:1)

我的移动平均线功能,没有numpy功能:

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

答案 5 :(得分:0)

我认为:

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

但我总是要仔细检查指数正在做我期望的事情。您想要的范围是(0,5,10,...),数据[0:6]将为您提供数据[0] ...数据[5]

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

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