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

问题描述 投票:-2回答:1

我正在寻找一个有效的numpy解决方案来解决以下问题:

我有一个N乘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)
python numpy numpy-ndarray
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.