Kara - 1 year ago 264
Python Question

How to calculate moving average in Python 3?

Let's say I have a list:

``````y = ['1', '2', '3', '4','5','6','7','8','9','10']
``````

I want to create a function that calculates the moving n-day average.
So if
`n`
was 5, I would want my code to calculate the first 1-5, add it and find the average, which would be 3.0, then go on to 2-6, calculate the average, which would be 4.0, then 3-7, 4-8, 5-9, 6-10.

I don't want to calculate the first n-1 days, so starting from the nth day, it'll count the previous days.

``````def moving_average(x:'list of prices', n):
for num in range(len(x)+1):
print(x[num-n:num])
``````

This seems to print out what I want:

``````[]
[]
[]
[]
[]

['1', '2', '3', '4', '5']

['2', '3', '4', '5', '6']

['3', '4', '5', '6', '7']

['4', '5', '6', '7', '8']

['5', '6', '7', '8', '9']

['6', '7', '8', '9', '10']
``````

However, I don't know how to calculate the numbers inside those lists. Any ideas?

There is a great sliding window generator in an old version of the Python docs with `itertools` examples:

``````from itertools import islice

def window(seq, n=2):
"Returns a sliding window (of width n) over data from the iterable"
"   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
``````

Using that your moving averages is trivial:

``````from __future__ import division  # For Python 2

def moving_averages(values, size):
for selection in window(values, size):
yield sum(selection) / size
``````

Running this against your input (mapping the strings to integers) gives:

``````>>> y= ['1', '2', '3', '4','5','6','7','8','9','10']
>>> for avg in moving_averages(map(int, y), 5):
...     print(avg)
...
3.0
4.0
5.0
6.0
7.0
8.0
``````

To return `None` the first `n - 1` iterations for 'incomplete' sets, just expand the `moving_averages` function a little:

``````def moving_averages(values, size):
for _ in range(size - 1):
yield None
for selection in window(values, size):
yield sum(selection) / size
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download