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?
Asked
Active
Viewed 2.1k times
19
-
1How do you define "n nearest entries"? Is this a square region centered on the current entry (eg 5x5)? – Peter Gibson Apr 10 '14 at 23:03
-
@PeterGibson That would work fine-- the exact shape of the region doesn't matter for my use case. – Sean Mackesey Apr 11 '14 at 01:21
1 Answers
31
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).

DarkCygnus
- 7,420
- 4
- 36
- 59

shx2
- 61,779
- 13
- 130
- 153
-
1Thanks, but the linked documentation is a little sparse. What would be the exact call I would use if my image is called `img` and I want to calculate the average of a 5x5 grid around each pixel? – Sean Mackesey Apr 14 '14 at 15:30
-
It's a bummer you can't specify a different `mode` for each axis. Or, wait, I guess that wouldn't work. – abcd Mar 24 '15 at 01:08