es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo se vectoriza el promedio móvil?

Ya conozco la convolución y lo he hecho. Sin embargo, he escuchado que puede ser aún más rápido.

Ejemplo de datos:

0    2
1    1
2    0
3    0
4    2
5    2
6    1
7    4
8    2
9    3

Salida:

0    NaN
1    NaN
2    NaN
3    NaN
4    1.0
5    1.0
6    1.0
7    1.8
8    2.2
9    2.4

Las soluciones que ya conozco son:

df["x"].rolling(5).mean()

Luego, la solución con convolución:

c = np.convolve(df["x"], np.ones(5), mode="valid")
c / (np.ones(len(c))*5)

Digamos que tienes una ventana de tamaño 5, entonces el cambio en el cálculo en movimiento siempre es xn – xn-5 / 5, donde xn es el valor actual y xn-5 es el que se elimina del promedio móvil.

Los primeros 5 aún tendrían que calcularse a la manera antigua y luego se agregaría el promedio de los primeros 5 elementos al cálculo en movimiento.

No estoy seguro de si es más rápido, de todos modos me gustaría implementarlo.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Un enfoque para potencialmente hacer más rápido el cálculo rodante es utilizar la vectorización. En lugar de utilizar la función rodante incorporada, podemos utilizar las funciones de manipulación de matrices de numpy para calcular el promedio rodante.

    Aquí tienes una implementación de ejemplo:

    import numpy as np
    
    # Datos de ejemplo
    data = np.array([2,1,0,0,2,2,1,4,2,3])
    
    # Tamaño de la ventana rodante
    window = 5
    
    # Calcular la suma rodante utilizando cumsum
    cumsum = np.cumsum(np.insert(data, 0, 0))
    rolling_sum = cumsum[window:] - cumsum[:-window]
    
    # Calcular el promedio rodante
    rolling_mean = rolling_sum / window
    
    # Concatenar valores NaN para los primeros "window" elementos
    output = np.concatenate((np.full(window-1, np.nan), rolling_mean))
    
    print(output)
    

    Este enfoque utiliza la función cumsum de numpy para calcular la suma acumulativa de los datos con un 0 adicional al principio. Luego, podemos calcular la suma rodante restando la suma acumulativa de los elementos que se “eliminan” de la suma acumulativa del elemento actual y los “window-1” elementos anteriores. Finalmente, dividimos la suma rodante por el tamaño de la ventana para obtener la media rodante.

    Para manejar el caso en el que no hay suficientes elementos para una ventana rodante completa, concatenamos valores NaN para los primeros “window-1” elementos.

    El uso de este enfoque vectorizado puede ser más rápido que el uso de la función rodante incorporada o el método de convolución, pero también puede depender del tamaño de los datos y el tamaño de la ventana.

Comments are closed.