我再次使用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()
我得到了这个:
非常感谢^^:)
答案 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;同样,看看数学是否有意义。
答案 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]