Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you're looking for other interesting ways to solve the problem, here is an answer using <em>itertools</em>:</p> <pre><code>import datetime as dt from collections import deque from itertools import tee, islice, izip def dayiter(start, end): one = dt.timedelta(days=1) day = start while day &lt;= end: yield day day += one def moving_average(mapping, window, dft=0): n = float(window) t1, t2 = tee(dayiter(min(mapping), max(mapping))) s = sum(mapping.get(day, dft) for day in islice(t2, window)) yield s / n for olddate, newdate in izip(t1, t2): oldvalue = mapping.get(olddate, dft) newvalue = mapping.get(newdate, dft) s += newvalue - oldvalue yield s / n example = {dt.datetime(2008, 1, 1) : 5, dt.datetime(2008, 1, 2) : 6, dt.datetime(2008, 1, 3) : 7, dt.datetime(2008, 1, 4) : 9, dt.datetime(2008, 1, 5) : 12, dt.datetime(2008, 1, 6) : 15, dt.datetime(2008, 1, 7) : 20, dt.datetime(2008, 1, 8) : 22, dt.datetime(2008, 1, 9) : 25, dt.datetime(2008, 1, 10) : 35} for ma in moving_average(example, window=3): print ma </code></pre> <p>The ideas involved are:</p> <ul> <li><p>Use a simple generator to make a date iterator that loops over consecutive days from the lowest to the highest.</p></li> <li><p>Use <em>itertools.tee</em> to construct a pair of iterators over the oldest data and the newest data (the front of the data window and the back).</p></li> <li><p>Keep a running sum in a variable <em>s</em>. On each iteration, update <em>s</em> by subtracting the oldest value and adding the newest value.</p></li> <li><p>This solution is space efficient (it keeps no more than <em>window</em> values in memory) and it is time efficient, one addition and one subtraction for each day regardless of the size of the window.</p></li> <li><p>Handle missing days by defaulting to zero. There are other strategies that could be used for missing days (like using the current moving average as a default or adjusting <em>n</em> up and down to reflect the number of actual data points in the window). </p></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload