calculate exponential moving average in python
Question: I have a range of dates and a measurement on each of those dates. I'd like to
calculate an exponential moving average for each of the dates. Does anybody
know how to do this?

I'm new to python. It doesn't appear that averages are built into the standard
python library, which strikes me as a little odd. Maybe I'm not looking in the
right place.

So, given the following code, how could I calculate the moving weighted
average of IQ points for calendar dates?

    
    
    from datetime import date
    days = [date(2008,1,1), date(2008,1,2), date(2008,1,7)]
    IQ = [110, 105, 90]
    

(there's probably a better way to structure the data, any advice would be
appreciated)


Answer: EDIT: It seems that
[`mov_average_expw()`](http://www.scipy.org/scipy/scikits/browser/trunk/timeseries/scikits/timeseries/lib/moving_funcs.py)
function from
[scikits.timeseries.lib.moving_funcs](http://pytseries.sourceforge.net/lib/moving_funcs.html)
submodule from [SciKits](http://scikits.appspot.com/) (add-on toolkits that
complement [SciPy](http://scipy.org/)) better suits the wording of your
question.

* * *

To calculate an [exponential
smoothing](http://en.wikipedia.org/wiki/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 namedtuple
    from operator    import itemgetter
    
    def 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.py
    IQData(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
    

