NumPy version of “Exponential weighted moving average”, equivalent to pandas.ewm().mean()

后端 未结 12 778
一生所求
一生所求 2020-11-27 12:30

How do I get the exponential weighted moving average in NumPy just like the following in pandas?

import pandas as pd
import pandas_datareader as pdr
from dat         


        
12条回答
  •  猫巷女王i
    2020-11-27 12:44

    Here's my implementation for 1D input arrays with infinite window size. As it uses large numbers, it works only with input arrays with elements of absolute value < 1e16, when using float32, but that should normally be the case.

    The idea is to reshape the input array into slices of a limited length, so that no overflow occurs, and then doing the ewm calculation with each slice separately.

    def ewm(x, alpha):
        """
        Returns the exponentially weighted mean y of a numpy array x with scaling factor alpha
        y[0] = x[0]
        y[j] = (1. - alpha) * y[j-1] + alpha * x[j],  for j > 0
    
        x -- 1D numpy array
        alpha -- float
        """
    
        n = int(-100. / np.log(1.-alpha)) # Makes sure that the first and last elements in f are very big and very small (about 1e22 and 1e-22)
        f = np.exp(np.arange(1-n, n, 2) * (0.5 * np.log(1. - alpha))) # Scaling factor for each slice
        tmp = (np.resize(x, ((len(x) + n - 1) // n, n)) / f * alpha).cumsum(axis=1) * f # Get ewm for each slice of length n
    
        # Add the last value of each previous slice to the next slice with corresponding scaling factor f and return result
        return np.resize(tmp + np.tensordot(np.append(x[0], np.roll(tmp.T[n-1], 1)[1:]), f * ((1. - alpha) / f[0]), axes=0), len(x))
    

提交回复
热议问题