Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy Two-Dimensional Moving Average

I have a 2d numpy array. I want to take the average value of the n nearest entries to each entry, just like taking a sliding average over a one-dimensional array. What is the cleanest way to do this?

like image 322
Sean Mackesey Avatar asked Apr 10 '14 22:04

Sean Mackesey


People also ask

How do you average a 2D array in Python?

To calculate the average of all values in a 2 dimensional NumPy array called matrix, use the numpy. average(matrix) function. The output will display a numpy array that has three average values, one per column of the input given array.

How do you find the moving average of a NumPy array?

Method 1: Using Numpy cumsum() which returns the array of the cumulative sum of elements of the given array. A moving average can be calculated by dividing the cumulative sum of elements by window size.

How do you find the average of a two dimensional array?

To calculate the average separately for each column of the 2D array, use the function call np. average(matrix, axis=0) setting the axis argument to 0. What is this? The resulting array has three average values, one per column of the input matrix .

How do you find the moving average of an array?

The kth-order moving average of the array X consisting of primitive data values is the average of the last k elements up to the i-th point of X . That is, A [i] = (X [i-k + 1] + X [i-k + 2] + ... + X [i]) / k . If the number of the preceding element (including itself) is smaller than k, Calculate as an average.


1 Answers

This is a similar concept to applying a filter to an image.

Fortunately, scipy.ndimage.filters has a bunch of functions to do that. The one you're after is scipy.ndimage.uniform_filter.

Can be used like this:

a
=> 
array([[  0.,   1.,   2.,   3.,   4.],
       [  5.,   6.,   7.,   8.,   9.],
       [ 10.,  11.,  12.,  13.,  14.],
       [ 15.,  16.,  17.,  18.,  19.],
       [ 20.,  21.,  22.,  23.,  24.]])

uniform_filter(a, size=3, mode='constant')
=> 
array([[  1.33333333,   2.33333333,   3.        ,   3.66666667,          2.66666667],
       [  3.66666667,   6.        ,   7.        ,   8.        ,          5.66666667],
       [  7.        ,  11.        ,  12.        ,  13.        ,          9.        ],
       [ 10.33333333,  16.        ,  17.        ,  18.        ,         12.33333333],
       [  8.        ,  12.33333333,  13.        ,  13.66666667,          9.33333333]])

If you want a 5x5 filter, use size=5. The mode option controls how the edges are treated. You didn't specify how you want to handle the edges. In this example, the "constant" mode means it treats each item outside the bounds of the array as a constant value of 0 (0 is the default, which can be overridden).

like image 185
shx2 Avatar answered Sep 17 '22 07:09

shx2