从Python中的数据点中找到移动平均数
我在Python中再玩一遍,并且找到了一个带有示例的整洁书。其中一个例子是绘制一些数据。我有一个两列的.txt文件,我有数据。我绘制的数据不错,但在运动,它说:进一步修改程序来计算和绘制数据,通过规定的移动平均:从Python中的数据点中找到移动平均数
$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中的和,并将数据中的每10个点取平均值,直到结束点数?
我看着书,但没有发现任何可以解释这一点:\
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()
而且我得到了这一点:
非常感谢你^^ :)
Before reading this answer, bear in mind that there is another answer below, from Roman Kh, which uses
numpy.cumsum
and is MUCH MUCH FASTER than this one.
最佳
一种常见方式替换每个5 10和4施加移动/到一个信号的滑动平均(或任何其它的滑动窗函数)是通过使用numpy.convolve()
。
def movingaverage(interval, window_size):
window = numpy.ones(int(window_size))/float(window_size)
return numpy.convolve(interval, window, 'same')
在这里,时间间隔为您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()
希望这有助于!
这里我得到的错误: 回溯(最近呼叫最后): 文件“C:/用户/ ***** /桌面/ sunspots_plot.py”,第18行,在
嗯,这意味着你没有导入numpy。实际上,你只是从中导入了一些函数:'linspace'和'loadtxt'。你应该添加'ones'和'convolve'; o) – heltonbiker 2012-07-05 21:04:46
我编辑了我的代码,现在我有了图像,但平均值只在图的最后部分,我应该手动更改间隔来排序? – 2012-07-05 21:09:49
我觉得是这样的:
aves = [sum(data[i:i+6]) for i in range(0, len(data), 5)]
但我总是要仔细检查指标都在做什么,我的期望。你想要的范围是(0,5,10,...),data [0:6]会给你数据[0] ... data [5]
ETA:oops,当然,不是总和。因此,实际使用您的代码和公式:
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]
ravgs = [sum(data[i:i+5])/5. for i in range(len(data)-4)]
这不是最有效的方法,但它会给你的答案,我还不清楚,如果你的窗口是5分或10。如果其10与9.
移动平均值是一个卷积,numpy比大多数纯Python操作要快。这会给你10点移动平均线。
import numpy as np
smoothed = np.convolve(data, np.ones(10)/10)
我也要强烈使用大包熊猫建议,如果你是时间序列数据的工作。有一些不错的moving average operations built in。
我得到错误: 回溯(最近的通话最后): 文件“ C:\ Python26“C:/ Users/*****/Desktop/sunspots_plot.py”,第7行,在
Thats您的案例中的b/c数据是多维numpy数组,您应该传递一维数组。在你的情况下,它会平滑= np.convolve(y,np.ones/10) – reptilicus 2012-07-06 14:55:55
+10到“使用熊猫”的建议。对于每个案例来说都不是很完美,但是对于阅读这篇文章的人来说,可能会节省很多麻烦。 – Owen 2017-01-25 08:58:58
接受的答案存在问题。我认为我们需要使用“有效”而不是“相同”这里 - return numpy.convolve(interval, window, 'same')
。
作为一个实施例尝试这个数据集= [1,5,7,2,6,7,8,2,2,7,8,3,7,3,7,3,15,6]
的MA - 结果应该是[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)
试试这个有效的&相同,看看数学是否有意义。
还没有尝试过,但我会研究它,它是自从我使用Python进行编码以来已经有一段时间了 – 2014-10-29 07:07:06
@dingo_d为什么不快速尝试一下生锈的代码(以及示例数据集(作为一个简单列表),我发布了?对于一些懒惰的人(比如我一开始就是这样) - 它的掩码事实上,移动平均数是不正确的,可能你应该考虑编辑你的原始答案,我昨天试了一下,双重检查让我从面对报告到Cxo水平时面临不好的问题,你只需要尝试一次相同的移动平均值与“有效”和其他时间与“相同” - - 一旦你确信给我一些爱(aka-up-vote) – ekta 2014-10-29 07:16:22
我目前工作,所以我没有访问Python,但是当我'在家我会试试:) – 2014-10-29 07:25:18
由于numpy.convolve是相当缓慢的,那些谁需要一个快速解决方案执行可能更喜欢一个更容易理解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比卷积快了约30-40倍。
我想如果我今天要实现一个离线移动平均线,我会从一开始就使用您的解决方案,而不是使用卷积。其实我很惊讶这个答案还没有收到很多upvotes ... – heltonbiker 2016-08-09 17:13:58
'step'参数在哪里? – 2016-08-11 17:03:45
@ roman-kh,如果你能看看这个和谢谢,我将不胜感激。 https://*.com/questions/45839123/python-how-can-we-smooth-a-noisy-signal-using-moving-average – 2017-08-23 12:17:54
我的移动平均线功能,无需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
对不起,添加第一行:from _future_ import division。否则输出将是int而不是float – 2015-12-23 22:09:39
@Arnanda_An,你可以在'1'中用一个小数点强制在Python 2中进行浮点除法:m =(m * i + A [i])/(i + 1 。)' – 2017-08-02 14:38:12
这是奇怪的。由于我们没有你的txt文件,所以不可能在这里测试,但我认为'xlim'行不应该被使用(以防万一) – heltonbiker 2012-07-05 21:11:30
我从这里得到了点:http:// www-personal。 umich.edu/~mejn/computational-physics/sunspots.dat 并删除xlim没有帮助:\ – 2012-07-05 21:14:29
我犯了一个错误的代码!您必须在y阵列上执行平均值,而不是x: 'y_av = movingaverage(y,r)' 'plot(x,y_av)'。我想,你可以再次使用xlim。 – heltonbiker 2012-07-05 21:20:15