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

在Python中从数据点查找移动平均值,python,plot,sum,average,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, sh

我又在玩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的密码成功了

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()
我得到了这个:


非常感谢^^:)

我想:

aves = [sum(data[i:i+6]) for i in range(0, len(data), 5)]
但我总是要仔细检查指数是否符合我的预期。您想要的范围是(0,5,10,…),数据[0:6]将为您提供数据[0]…数据[5]

埃塔:哦,当然,你想要的是平均值而不是总和。因此,实际使用您的代码和公式:

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

在阅读此答案之前,请记住下面还有另一个答案,来自Roman Kh,它使用
numpy.cumsum
,比这个答案快得多


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

这里,间隔是您的代码> x>代码>数组,而<>代码>窗口大小> <代码>是要考虑的样本数。窗口将以每个样本为中心,因此它在当前样本之前和之后采集样本以计算平均值。您的代码将变成:

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将比大多数纯python操作更快。这将给你10点移动平均线

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

如果您正在处理timeseries数据,我还建议您使用大熊猫软件包。有一些不错的

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

作为一个例子,尝试一下这个数据集的MA,这一数据集的MA,一个数据集的MA,一个数据集的MA,一个例子,一个例子,一个例子,一个例子,一个测试,一个例子,一个例子,一个例子,一个例子,一个例子,一个测试,一个数据集的MA,一个数据集的MA,一个数据集的MA,1,5,5,5,7,7,7,7,7,7,7,7,7,7,7,3,7,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,6,6,15,5,5,5,5,5,6,5,6,5,5,6,6,6,6,6,6,4.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) 
result=[]
数据集=[1,5,7,2,6,7,8,2,2,7,8,3,7,3,7,3,15,6]
窗口大小=5
对于xrange(len(dataset))中的索引:
如果索引如numpy.convalve相当慢,那些需要快速执行解决方案的人可能更喜欢更容易理解的累积和方法。代码如下:

cumsum_vec = numpy.cumsum(numpy.insert(data, 0, 0)) 
ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width
其中数据包含您的数据,ma_vec将包含窗口宽度和长度的移动平均值


平均而言,cumsum比convolve快30-40倍。

我的移动平均函数,没有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

有了这个,我得到了一堆数组,当我试图绘制它们时,我得到了错误:\n对不起,没有纠正错误,应该是y1[I-r:I+r]而不是数据,而且不管怎样,y1有len(y1)点,y2有len(y1)/2r点,所以…您想将它们分别添加到图形中。改为使用卷积解决方案!同样,对于y2,我得到它们是[array[number,number],array[number,number]…]:\n我需要得到要绘制的数字:\I得到错误:回溯(最近一次调用):文件“C:/Users/*****/Desktop/sunspots\u plot.py”,第7行,在平滑的=np.convalve(data,np.ones(10)/(10))文件“C:\Python26\lib\site packages\numpy\core\numeric.py”中,第787行,在卷积返回多数组中。关联(a,v[::-1],模式)值错误:对象对于所需数组太深。在您的情况下,b/c数据是多维numpy数组,您应该传递一维数组。在您的例子中,对于“使用熊猫”建议,它将被平滑=np.convalve(y,np.ones/10)+10。不是每种情况都完美,但可能会为阅读这篇文章的普通人省去很多麻烦。@爬行动物,这似乎很酷,但似乎并没有改善我在这里遇到的类似问题,如果你能看一下,我将不胜感激。这里我得到了错误:回溯(最近一次调用last):文件“C:/Users/*****/Desktop/sunspots_plot.py”,第18行,在x_av=movingaverage(x,5)文件“C:/Users/*****/Desktop/sunspots_plot.py”,第8行,在movingaverage window=numpy.ones(int(window\u size))/float(window\u size)name错误:全局名称“numpy”没有很好地定义,那意味着你没有进口numpy。实际上,您只是从中导入了一些函数:
linspace
loadtxt
。你应该加上
one
convalve
;o) 我编辑了我的代码,现在我有了图像,但平均值仅在图表的最后一部分,我是否应该手动更改间隔以进行排序?问题是卷积速度非常慢。在下面,您可能会发现一个基于numpy.cumsum()的更快的解决方案。我发现这个解决方案工作得很好,但在数据边缘不起作用。它添加了虚假的低值,这很奇怪。由于我们没有您的txt文件,因此无法在此处进行测试,但我认为不应使用
xlim
行(以防万一),我从这里得到了要点:删除xlim没有帮助:\n我在代码中犯了一个错误!你必须完成这个任务
cumsum_vec = numpy.cumsum(numpy.insert(data, 0, 0)) 
ma_vec = (cumsum_vec[window_width:] - cumsum_vec[:-window_width]) / window_width
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