calculate exponential moving average in python calculate exponential moving average in python python python

calculate exponential moving average in python


EDIT:It seems that mov_average_expw() function from scikits.timeseries.lib.moving_funcs submodule from SciKits (add-on toolkits that complement SciPy) better suits the wording of your question.


To calculate an exponential smoothing of your data with a smoothing factor alpha (it is (1 - alpha) in Wikipedia's terms):

>>> alpha = 0.5>>> assert 0 < alpha <= 1.0>>> av = sum(alpha**n.days * iq ...     for n, iq in map(lambda (day, iq), today=max(days): (today-day, iq), ...         sorted(zip(days, IQ), key=lambda p: p[0], reverse=True)))95.0

The above is not pretty, so let's refactor it a bit:

from collections import namedtuplefrom operator    import itemgetterdef smooth(iq_data, alpha=1, today=None):    """Perform exponential smoothing with factor `alpha`.    Time period is a day.    Each time period the value of `iq` drops `alpha` times.    The most recent data is the most valuable one.    """    assert 0 < alpha <= 1    if alpha == 1: # no smoothing        return sum(map(itemgetter(1), iq_data))    if today is None:        today = max(map(itemgetter(0), iq_data))    return sum(alpha**((today - date).days) * iq for date, iq in iq_data)IQData = namedtuple("IQData", "date iq")if __name__ == "__main__":    from datetime import date    days = [date(2008,1,1), date(2008,1,2), date(2008,1,7)]    IQ = [110, 105, 90]    iqdata = list(map(IQData, days, IQ))    print("\n".join(map(str, iqdata)))    print(smooth(iqdata, alpha=0.5))

Example:

$ python26 smooth.pyIQData(date=datetime.date(2008, 1, 1), iq=110)IQData(date=datetime.date(2008, 1, 2), iq=105)IQData(date=datetime.date(2008, 1, 7), iq=90)95.0


I did a bit of googling and I found the following sample code (http://osdir.com/ml/python.matplotlib.general/2005-04/msg00044.html):

def ema(s, n):    """    returns an n period exponential moving average for    the time series s    s is a list ordered from oldest (index 0) to most    recent (index -1)    n is an integer    returns a numeric array of the exponential    moving average    """    s = array(s)    ema = []    j = 1    #get n sma first and calculate the next n period ema    sma = sum(s[:n]) / n    multiplier = 2 / float(1 + n)    ema.append(sma)    #EMA(current) = ( (Price(current) - EMA(prev) ) x Multiplier) + EMA(prev)    ema.append(( (s[n] - sma) * multiplier) + sma)    #now calculate the rest of the values    for i in s[n+1:]:        tmp = ( (i - ema[j]) * multiplier) + ema[j]        j = j + 1        ema.append(tmp)    return ema


I'm always calculating EMAs with Pandas:

Here is an example how to do it:

import pandas as pdimport numpy as npdef ema(values, period):    values = np.array(values)    return pd.ewma(values, span=period)[-1]values = [9, 5, 10, 16, 5]period = 5print ema(values, period)

More infos about Pandas EWMA:

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.ewma.html