Trouver une moyenne mobile à partir de points de données en Python

je joue encore un peu en Python, et j'ai trouvé un livre soigné avec des exemples. L'un des exemples est de tracer certaines données. J'ai un .fichier txt avec deux colonnes et j'ai les données. J'ai tracé les données très bien, mais dans l'exercice il est dit: modifier votre programme plus loin pour calculer et tracer la moyenne courante des données, défini par:

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

r=5 dans ce cas (et l' y_k est la deuxième colonne du fichier de données). Demandez au programme de tracer à la fois les données originales et la moyenne sur le même graphique.

pour l'instant j'ai ceci:

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

alors comment calculer la somme? Dans Mathematica, c'est simple car c'est une manipulation symbolique (Sum[i, {i,0,10}] par exemple), mais comment calculer sum en python qui prend tous les dix points dans les données et les moyennes, et le fait jusqu'à la fin des points?

j'ai regardé le livre, mais rien trouvé qui pourrait expliquer ceci :


code de heltonbiker a fait le tour ^^ :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()

Et j'ai obtenu ceci:

image

Merci beaucoup ^^ :)

34
demandé sur dingo_d 0000-00-00 00:00:00

3 réponses

avant de lire cette réponse, gardez à l'esprit qu'il y a une autre réponse ci-dessous, de Roman Kh, qui utilise numpy.cumsum et il est BEAUCOUP BEAUCOUP plus RAPIDE que ce dernier.


une façon courante d'appliquer une moyenne mobile / coulissante (ou toute autre fonction de fenêtre coulissante) à un signal est d'utiliser numpy.convolve().

def movingaverage(interval, window_size):
    window = numpy.ones(int(window_size))/float(window_size)
    return numpy.convolve(interval, window, 'same')

ici, l'intervalle est votrex array, et window_size est le nombre d'échantillons à prendre en compte. La fenêtre sera centré sur chaque échantillon, il prend des échantillons avant et après l'échantillon actuel afin de calculer la moyenne. Votre code deviendrait:

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

Espérons que cette aide!

70
répondu heltonbiker 2017-05-26 19:16:53

numpy.convolve est assez lent, ceux qui ont besoin d'une solution performante rapide pourraient préférer une plus facile à comprendre cumsum approche. Voici le code:

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

contient vos données, et ma_vec contiendra des moyennes mobiles de window_width longueur.

moyenne cumsum est environ 30-40 fois plus rapide que convolve.

38
répondu Roman Kh 2015-12-21 02:00:15

une moyenne mobile est une convolution, et numpy sera plus rapide que la plupart des opérations python pures. Vous obtiendrez ainsi une moyenne mobile de 10 points.

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

je voudrais aussi fortement suggérez d'utiliser le paquet great pandas si vous travaillez avec des données de série temporelle. Il y a quelques belles moyenne mobile des opérations construit en.

24
répondu reptilicus 2012-12-30 18:22:01