1

I am looking for an efficient way to find the mean of of values with a certain radius of an element in a 2D NumPy array, excluding the center point and values < 0.

My current method is to create a disc shaped mask (using the method here) and find the mean of points within this mask. This is taking too long however...over 10 minutes to calculate ~18000 points within my 300x300 array.

The array I want to find means within is here titled "arr"

def radMask(index,radius,array,insert):
  a,b = index
  nx,ny = array.shape
  y,x = np.ogrid[-a:nx-a,-b:ny-b]
  mask = x*x + y*y <= radius*radius
  array[mask] = insert

  return array

arr_mask          = np.zeros_like(arr).astype(int)
arr_mask          = radMask(center, radius, arr_mask, 1)
arr_mask[arr < 0] = 0  #Exclude points with no echo
arr_mask[ind]     = 0  #Exclude center point

arr_mean = 0
if np.any(dbz_bg):
    arr_mean = sp.mean(arr[arr_mask])

Is there any more efficient way to do this? I've looked into some of the image processing filters/tools but can't quite wrap my head around it.

Community
  • 1
  • 1
hm8
  • 1,381
  • 3
  • 21
  • 41

1 Answers1

1

is this helpful? This takes only a couple of seconds on my laptop for ~ 18000 points:

import numpy as np

#generate a random 300x300 matrix for testing
inputMat = np.random.random((300,300))
radius=50

def radMask(index,radius,array):
  a,b = index
  nx,ny = array.shape
  y,x = np.ogrid[-a:nx-a,-b:ny-b]
  mask = x*x + y*y <= radius*radius

  return mask


#meanAll is going to store ~18000 points
meanAll=np.zeros((130,130))

for x in range(130):
    for y in range(130):
        centerMask=(x,y)
        mask=radMask(centerMask,radius,inputMat)
        #un-mask center and values below 0
        mask[centerMask]=False
        mask[inputMat<0]=False

        #get the mean
        meanAll[x,y]=np.mean(inputMat[mask])
jlarsch
  • 2,217
  • 4
  • 22
  • 44