Numpy距阵列中心

时间:2016-11-26 17:19:22

标签: python arrays performance numpy vectorization

我有一个数组的中心点,

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

我有一个二进制图像数组array,其形状的相关像素设置为0(所有其他像素都是255)。

我需要从数组中心到所有像素设置为零的平均距离,我需要它进行矢量化(它不能在python级别解释 - 慢慢的方式)。

这就是我所拥有的,现在我被卡住了,因为我发现其他答案指向SciPy,但服务器支持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])

我无法在不对np.where进行多次调用并使用python for循环遍历形状索引的情况下弄清楚如何执行此操作。必须有一种方法可以在numpy代码中完成这个... ??

以下是适用的非矢量化版本:

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

2 个答案:

答案 0 :(得分:4)

方法#1:使用NumPy broadcasting -

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

方法#2:使用np.einsum -

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

答案 1 :(得分:3)

仅用于说明我使用随机数组:

>>> import numpy as np
>>> arr = (np.random.random((5, 5)) > 0.5).astype(int)
>>> arr
array([[0, 0, 0, 1, 0],
       [0, 0, 1, 1, 1],
       [0, 1, 0, 0, 1],
       [1, 0, 0, 1, 0],
       [1, 0, 1, 0, 1]])
>>> center = (2, 2)  # use your center here

要获得距离,我将使用meshgrid:

>>> grid_x, grid_y = np.mgrid[0:arr.shape[0], 0:arr.shape[1]]
>>> grid_x
array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4]])
>>> grid_y
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])

我们将网格移动到中心的坐标:

>>> grid_x = grid_x - center[0]
>>> grid_y = grid_y - center[1]

最后,我们使用np.hypot函数计算距离(几乎与np.sqrt(x**2 + y**2)相同),但仅使用arr == 0处的点:

>>> distances = np.hypot(grid_x[arr == 0], grid_y[arr == 0])

现在是时候计算距离的平均值/平均值了:

>>> np.mean(distances)
2.767080465988093