standard for python plot sum average

for - Encontrar promedio móvil de puntos de datos en Python



numpy min (7)

Estoy jugando un poco más en Python y encontré un buen libro con ejemplos. Uno de los ejemplos es trazar algunos datos. Tengo un archivo .txt con dos columnas y tengo la información. Tracé los datos muy bien, pero en el ejercicio dice: Modifique más su programa para calcular y graficar el promedio continuo de los datos, definido por:

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

donde r=5 en este caso (y y_k es la segunda columna en el archivo de datos). Haga que el programa grabe los datos originales y el promedio continuo en el mismo gráfico.

Hasta ahora tengo esto:

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

Entonces, ¿cómo calculo la suma? En Mathematica es simple ya que es manipulación simbólica (Sum [i, {i, 0,10}] por ejemplo), pero cómo calcular la suma en python que toma cada diez puntos en los datos y los promedia, y lo hace hasta el final de puntos?

Miré el libro, pero no encontré nada que explicara esto: /

El código de Heltonbiker hizo el truco ^^: 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()

Y obtuve esto:

Muchas gracias ^^ :)


Antes de leer esta respuesta, tenga en cuenta que hay otra respuesta más abajo, de Roman Kh, que usa numpy.cumsum y es MUCHO MÁS RÁPIDO que este.

La mejor forma común de aplicar un promedio móvil / deslizante (o cualquier otra función de ventana deslizante) a una señal es usando numpy.convolve() .

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

Aquí, interval es tu matriz x , y window_size es la cantidad de muestras a considerar. La ventana se centrará en cada muestra, por lo que toma muestras antes y después de la muestra actual para calcular el promedio. Tu código se convertiría en:

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

¡Espero que esto ayude!


Como numpy.convolve es bastante lento, aquellos que necesitan una solución de rendimiento rápido pueden preferir un enfoque cumsum más fácil de entender. Aquí está el código:

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

donde los datos contienen sus datos, y ma_vec contendrá promedios móviles de la longitud de window_width .

En promedio, cumsum es aproximadamente 30-40 veces más rápido que convolve .


Creo que algo así como:

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

Pero siempre tengo que verificar que los índices estén haciendo lo que espero. El rango que desea es (0, 5, 10, ...) y datos [0: 6] le dará datos [0] ... datos [5]

ETA: uy, y quieres ave en lugar de suma, por supuesto. Entonces, en realidad, usa tu código y la fórmula:

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]


Hay un problema con la respuesta aceptada. Creo que necesitamos usar "válido" en lugar de "igual" aquí - return numpy.convolve(interval, window, ''same'') .

Como ejemplo, pruebe la MA de este conjunto de datos = [1,5,7,2,6,7,8,2,2,7,8,3,7,3,7,3,15,6] - el resultado debería ser [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] , pero tener "lo mismo" nos da una salida incorrecta de [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]

Código oxidado para probar esto -:

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)

Pruebe esto con valid & same y vea si las matemáticas tienen sentido.

Ver también -: http://sentdex.com/sentiment-analysisbig-data-and-python-tutorials-algorithmic-trading/how-to-chart-stocks-and-forex-doing-your-own-financial-charting/calculate-simple-moving-average-sma-python/


Mi función promedio móvil, sin función 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


Un promedio móvil es una convolución, y numpy será más rápido que la mayoría de las operaciones de python puro. Esto le dará el promedio móvil de 10 puntos.

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

También recomendaría encarecidamente utilizar el gran paquete de pandas si está trabajando con datos de series temporales. Hay algunas buenas operaciones de promedio móvil integradas .


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

Este no es el enfoque más eficiente pero dará su respuesta y no estoy seguro si su ventana tiene 5 puntos o 10. Si es 10, reemplace cada 5 con 10 y el 4 con 9.