# Moving average or running mean

### Question

Is there a scipy function or numpy function or module for python that calculates the running mean of a 1D array given a specific window?

1
155
11/22/2017 2:46:56 PM

For a short, fast solution that does the whole thing in one loop, without dependencies, the code below works great.

``````mylist = [1, 2, 3, 4, 5, 6, 7]
N = 3
cumsum, moving_aves = , []

for i, x in enumerate(mylist, 1):
cumsum.append(cumsum[i-1] + x)
if i>=N:
moving_ave = (cumsum[i] - cumsum[i-N])/N
#can do stuff with moving_ave here
moving_aves.append(moving_ave)
``````
19
6/28/2017 8:36:29 AM

UPD: more efficient solutions have been proposed by Alleo and jasaarim.

You can use `np.convolve` for that:

``````np.convolve(x, np.ones((N,))/N, mode='valid')
``````

# Explanation

The running mean is a case of the mathematical operation of convolution. For the running mean, you slide a window along the input and compute the mean of the window's contents. For discrete 1D signals, convolution is the same thing, except instead of the mean you compute an arbitrary linear combination, i.e. multiply each element by a corresponding coefficient and add up the results. Those coefficients, one for each position in the window, are sometimes called the convolution kernel. Now, the arithmetic mean of N values is `(x_1 + x_2 + ... + x_N) / N`, so the corresponding kernel is `(1/N, 1/N, ..., 1/N)`, and that's exactly what we get by using `np.ones((N,))/N`.

# Edges

The `mode` argument of `np.convolve` specifies how to handle the edges. I chose the `valid` mode here because I think that's how most people expect the running mean to work, but you may have other priorities. Here is a plot that illustrates the difference between the modes:

``````import numpy as np
import matplotlib.pyplot as plt
modes = ['full', 'same', 'valid']
for m in modes:
plt.plot(np.convolve(np.ones((200,)), np.ones((50,))/50, mode=m));
plt.axis([-10, 251, -.1, 1.1]);
plt.legend(modes, loc='lower center');
plt.show()
`````` 