计算两个python数组之间的欧几里得距离
Posted
技术标签:
【中文标题】计算两个python数组之间的欧几里得距离【英文标题】:Calculate Euclidean distance between two python arrays 【发布时间】:2020-06-10 15:18:27 【问题描述】:我想编写一个函数来计算list_a
中的坐标与list_b
中的每个坐标之间的欧几里得距离,并生成一个维度为a
行b
列的距离数组(其中@ 987654326@ 是list_a
中的坐标数,b
是list_b
中的坐标数。
注意:为了简单起见,我不想使用除 numpy 之外的任何库。
list_a = np.array([[0,1], [2,2], [5,4], [3,6], [4,2]])
list_b = np.array([[0,1],[5,4]])
运行函数会生成:
>>> np.array([[0., 5.830951894845301],
[2.236, 3.605551275463989],
[5.830951894845301, 0.],
[5.830951894845301, 2.8284271247461903],
[4.123105625617661, 2.23606797749979]])
我一直在尝试运行下面的
def run_euc(list_a,list_b):
euc_1 = [np.subtract(list_a, list_b)]
euc_2 = sum(sum([i**2 for i in euc_1]))
return np.sqrt(euc_2)
但我收到以下错误:
ValueError: operands could not be broadcast together with shapes (5,2) (2,2)
谢谢。
【问题讨论】:
请分享整个错误信息。euc_1 = [np.subtract(list_a, list_b)]
是干什么用的?
这能回答你的问题吗? Minimum Euclidean distance between points in two different Numpy arrays, not within
您希望您的代码如何提供欧几里得距离?您有一个包含五个点的向量,以及另一个包含两个点的向量。你不能减去不同长度的向量。
【参考方案1】:
使用scipy
,您可以计算每对之间的距离,如下所示:
import numpy as np
from scipy.spatial import distance
list_a = np.array([[0,1], [2,2], [5,4], [3,6], [4,2]])
list_b = np.array([[0,1],[5,4]])
dist = distance.cdist(list_a, list_b, 'euclidean')
print(dist)
结果:
array([[0. , 5.83095189],
[2.23606798, 3.60555128],
[5.83095189, 0. ],
[5.83095189, 2.82842712],
[4.12310563, 2.23606798]])
【讨论】:
【参考方案2】:我想知道是什么阻止您使用 Scipy。既然你反正用的是numpy,或许你可以试试用scipy,不是那么重。
为什么? 它有许多数学函数和高效的实现,可以充分利用您的计算能力。
考虑到这一点,这里有一个 distance_matrix 函数,正是您提到的目的。
具体来说,它采用您的 list_a(m x k 矩阵)和 list_b(n x k 矩阵)并输出 m x n 矩阵,两个矩阵中每对点之间的距离为 p-norm(欧几里得 p=2)。
from scipy.spatial import distance_matrix
distances = distance_matrix(list_a, list_b)
【讨论】:
【参考方案3】:我认为这可行
import numpy as np
def distance(x,y):
x=np.array(x)
y=np.array(y)
p=np.sum((x-y)**2)
d=np.sqrt(p)
return d
【讨论】:
【参考方案4】:我希望这能回答问题,但这是重复; Minimum Euclidean distance between points in two different Numpy arrays, not within
# Import package
import numpy as np
# Define unequal matrices
xy1 = np.array([[0,1], [2,2], [5,4], [3,6], [4,2]])
xy2 = np.array([[0,1],[5,4]])
P = np.add.outer(np.sum(xy1**2, axis=1), np.sum(xy2**2, axis=1))
N = np.dot(xy1, xy2.T)
dists = np.sqrt(P - 2*N)
print(dists)
【讨论】:
【参考方案5】:另一种方法是:
np.array(
[np.sqrt((list_a[:,1]-list_b[i,1])**2+(list_a[:,0]-list_b[i,0])**2) for i in range(len(list_b))]
).T
输出:
array([[0. , 5.83095189],
[2.23606798, 3.60555128],
[5.83095189, 0. ],
[5.83095189, 2.82842712],
[4.12310563, 2.23606798]])
这段代码可以写得更简单、更高效,所以如果你发现代码中有什么可以改进的地方,请在评论中告诉我。
【讨论】:
【参考方案6】:在这里,您可以只使用np.linalg.norm
来计算欧几里得距离。您的错误是由于 np.subtract 期望两个输入具有相同的长度。
import numpy as np
list_a = np.array([[0,1], [2,2], [5,4], [3,6], [4,2]])
list_b = np.array([[0,1],[5,4]])
def run_euc(list_a,list_b):
return np.array([[ np.linalg.norm(i-j) for j in list_b] for i in list_a])
print(run_euc(list_a, list_b))
代码产生:
[[0. 5.83095189]
[2.23606798 3.60555128]
[5.83095189 0. ]
[5.83095189 2.82842712]
[4.12310563 2.23606798]]
【讨论】:
我真的不明白跨不同大小的数组应用计算的语法。你有我可以使用的好的在线资源吗?尝试将您的列表理解复制到另一个具有不同数组形状并出现错误的类似问题中。谢谢 当我第一次开始编写列表解析时,我会明确地编写 for 循环,然后作为练习,我会将它们写在一行中,最外面的 for 循环仍然是最外层的 for 循环。跨度> 谢谢你;但是有没有办法在不使用循环的情况下做到这一点?据我了解,遍历数组在计算上很费力 其他答案提供的 scipy 解决方案怎么样以上是关于计算两个python数组之间的欧几里得距离的主要内容,如果未能解决你的问题,请参考以下文章