web-dev-qa-db-ja.com

Pythonのデータポイントから移動平均を見つける

私はPythonをもう一度使用します。例のあるすてきな本を見つけました。例の1つはデータをプロットすることです。2列の.txtファイルがあり、データ:データをうまくプロットしましたが、演習では次のように述べています。

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

どこ r=5この場合(およびy_kは、データファイルの2番目の列です)。プログラムに元のデータと移動平均の両方を同じグラフにプロットさせます。

これまでのところ私はこれを持っています:

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}]など)であるため簡単ですが、データの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()

そして、私はこれを得ました:

image

ありがとうございました^^ :)

41
dingo_d

この回答を読む前に、Roman Khからの別の回答があります。これは_numpy.cumsum_を使用し、これよりもはるかに高速です。


ベスト 移動平均/スライド平均(または他のスライドウィンドウ関数)を信号に適用する一般的な方法の1つは、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()
_

お役に立てれば!

74
heltonbiker

numpy.convolveはかなり遅いため、高速なソリューションを必要とする人は、より簡単に理解できるcumsumアプローチを好むかもしれません。コードは次のとおりです。

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

ここで、dataにはデータが含まれ、ma_vecにはwindow_width lengthの移動平均が含まれます。

平均して、cumsumconvolveより約30-40倍高速です。

51
Roman Kh

移動平均は畳み込みであり、numpyはほとんどの純粋なpython操作よりも高速です。これにより、10ポイントの移動平均が得られます。

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

また、強く時系列データで作業している場合は素晴らしいpandasパッケージを使用することをお勧めします。 組み込みの移動平均操作

25
reptilicus

受け入れられた回答に問題があります。 "same"の代わりに "valid"を使用する必要があると思いますここ-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) 

有効かつ同じでこれを試して、数学が理にかなっているかどうかを確認してください。

参照-: http://sentdex.com/sentiment-analysisbig-data-and-python-tutorials-algorithmic-trading/how-to-chart-stocks-and-forex-doing-your -独自の財務チャート/計算-シンプル-移動-平均-sma-python /

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

これは最も効率的なアプローチではありませんが、答えが得られます。ウィンドウが5ポイントまたは10であるかどうかはわかりません。

4
sizzzzlerz

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
1
Armanda_An

私は次のようなものだと思う:

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

しかし、私は常にインデックスが私が期待することをしていることを再確認する必要があります。必要な範囲は(0、5、10、...)で、data [0:6]はdata [0] ... data [5]を提供します

ETA:おっと、もちろんあなたは和よりもアベニューが欲しいです。したがって、実際にコードと式を使用します:

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]
0
dreadsci