## Question

Asked By – loopbackbee

There seems to be no function that simply calculates the moving average on numpy/scipy, leading to convoluted solutions.

My question is two-fold:

- What’s the easiest way to (correctly) implement a moving average with numpy?
- Since this seems non-trivial and error prone, is there a good reason not to have the batteries included in this case?

**Now we will see solution for issue: How to calculate rolling / moving average using python + NumPy / SciPy? **

## Answer

A simple way to achieve this is by using `np.convolve`

.

The idea behind this is to leverage the way the discrete convolution is computed and use it to return a *rolling mean*. This can be done by convolving with a sequence of `np.ones`

of a length equal to the sliding window length we want.

In order to do so we could define the following function:

```
def moving_average(x, w):
return np.convolve(x, np.ones(w), 'valid') / w
```

This function will be taking the convolution of the sequence `x`

and a sequence of ones of length `w`

. Note that the chosen `mode`

is `valid`

so that the convolution product is only given for points where the sequences overlap completely.

Some examples:

```
x = np.array([5,3,8,10,2,1,5,1,0,2])
```

For a moving average with a window of length `2`

we would have:

```
moving_average(x, 2)
# array([4. , 5.5, 9. , 6. , 1.5, 3. , 3. , 0.5, 1. ])
```

And for a window of length `4`

:

```
moving_average(x, 4)
# array([6.5 , 5.75, 5.25, 4.5 , 2.25, 1.75, 2. ])
```

## How does `convolve`

work?

Lets have a more in depth look at the way the discrete convolution is being computed.

The following function aims to replicate the way `np.convolve`

is computing the output values:

```
def mov_avg(x, w):
for m in range(len(x)-(w-1)):
yield sum(np.ones(w) * x[m:m+w]) / w
```

Which, for the same example above would also yield:

```
list(mov_avg(x, 2))
# [4.0, 5.5, 9.0, 6.0, 1.5, 3.0, 3.0, 0.5, 1.0]
```

So what is being done at each step is to take the inner product between the array of ones and the current * window*. In this case the multiplication by `np.ones(w)`

is superfluous given that we are directly taking the `sum`

of the sequence.

Bellow is an example of how the first outputs are computed so that it is a little clearer. Lets suppose we want a window of `w=4`

:

```
[1,1,1,1]
[5,3,8,10,2,1,5,1,0,2]
= (1*5 + 1*3 + 1*8 + 1*10) / w = 6.5
```

And the following output would be computed as:

```
[1,1,1,1]
[5,3,8,10,2,1,5,1,0,2]
= (1*3 + 1*8 + 1*10 + 1*2) / w = 5.75
```

And so on, returning a moving average of the sequence once all overlaps have been performed.

This question is answered By – yatu

**This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 **