bordeo bordeo - 1 year ago 64
Python Question

Numpy Average distance from array center

I have the center point of an array,

center_point = (array.shape[0]/2.,array.shape[1]/2.)

I have a binary image array,
, which has a shape whose relevant pixels are set to 0 (all other pixels are 255).

I need the average distance from the center of the array for all the pixels set to zero, and I need it to be vectorized (it can't be interpreted at the python level--way to slow).

Here is what I have, and now I am stuck, because the other answers I found point to SciPy, but the server only supports numpy.

centerpoint = array_center_point(shape_array)
distance_shape = np.zeros(size=shape_array.shape,dtype=float)

distance_shape[shape==0] = ...???

avg_distance = np.sum(distance_shape) / len(np.where(shape_array == 0)[0])

I can't figure out how to do this without making multiple calls to np.where and iterating through the shape indices with a python for loop. There must be a way to get this done inside the numpy code...??

Here is the non-vectorized version that works:

def avg_distance_from_center(shape_array):
center_point = array_center_point(shape_array)
distance_shape = np.zeros(shape=shape_array.shape, dtype=float)

shape_pixels = np.where(shape_array == 0)
total_distance = 0.
for i in range(len(shape_pixels[0])):
i_ind = float(shape_pixels[0][i])
j_ind = float(shape_pixels[1][i])

total_distance += ((i_ind - center_point[0])**2.0 + (j_ind - center_point[1])**2.0)**0.5
avg_distance = total_distance / len(shape_pixels[0])

return avg_distance

Answer Source

Approach #1 : With NumPy broadcasting -

np.sqrt(((np.argwhere(shape_array==0) - center_point)**2).sum(1)).mean()

Approach #2 : With np.einsum -

subs = (np.argwhere(a==0) - center_point)
out = np.sqrt(np.einsum('ij,ij->i',subs,subs)).mean()