从numpy中的任意坐标计算矩阵像元距离的有效方法

时间:2019-04-26 13:24:09

标签: python numpy numpy-ndarray

我正在寻找一种有效的numpy解决以下问题的方法:

我有一个N x N numpy矩阵。给定矩阵的任意i,j坐标(可以是十进制)和任意范围,我需要计算矩阵的每个单元格的值除以其到指定范围内的坐标的欧氏距离。

如果不清楚。给定坐标(5.2,5.5)和范围1。我需要获取像元(5,5)和像元本身的所有8个邻居,然后将这些像元值除以它们的距离(5.2,5.5)。

下面是该代码的一个非常慢的简单版本。

PROXIMITY_RANGE = 1
x = 5.2
y = 5.5
min_x = int(max(int(x) - PROXIMITY_RANGE, 0))
max_x = int(min(int(x) + PROXIMITY_RANGE, IMAGE_SIZE - 1))
min_y = int(max(int(y) - PROXIMITY_RANGE, 0))
max_y = int(min(int(y) + PROXIMITY_RANGE, IMAGE_SIZE - 1))

total = 0
for c_x in np.arange(min_x, max_x+1):
    for c_y in np.arange(min_y, max_y+1):
        distance = math.sqrt((x - c_x)**2 + (y - c_y)**2)
        total += input[c_y][c_x] / (1 + distance)

1 个答案:

答案 0 :(得分:0)

我们可以通过删除两个for循环并将其替换为numpy操作和切片来矢量化您的代码,从而提高效率。此外,删除标准python math.sqrt并替换为np.sqrt可以提高性能,尤其是在较大的矩阵中更明显

import numpy as np

IMAGE_SIZE = 100
input = np.random.randint(0, 100, size=(IMAGE_SIZE,IMAGE_SIZE))

PROXIMITY_RANGE = 1
x = 5.2
y = 5.5
min_x = int(max(int(x) - PROXIMITY_RANGE, 0))
max_x = int(min(int(x) + PROXIMITY_RANGE, IMAGE_SIZE - 1))
min_y = int(max(int(y) - PROXIMITY_RANGE, 0))
max_y = int(min(int(y) + PROXIMITY_RANGE, IMAGE_SIZE - 1))

size_y = max_y+1-min_y
size_x = max_x+1-min_x

#shape x and y to be like what you had in your for loops
y_vals = np.repeat(np.reshape(np.arange(min_y, max_y+1), (-1, size_y)), size_y, axis=0).transpose()
x_vals = np.tile(np.arange(min_x, max_x+1), (size_x, 1))

#extract the bits of the input we watn 
sliced_input = input[min_y:max_y+1, min_x:max_x+1]

# compute euclidean distance
distance = np.sqrt((x_vals - x)**2 + (y_vals - y)**2) + 1

#sum the total of the cell values
total = np.sum(sliced_input / distance)

print(total)

此外,您还遇到了一个错误,即距离始终为零。这是由于在您的for循环迭代器中覆盖了xy