我有两个数组,第一个np.array是来自的点,第二个np.array是我需要计算的所有距离。
示例:
import numpy as np
from_array = np.array([(0,1), (1,1), ..., (x,y)])
to_array = np.array([(5,1), (3,1), ..., (x,y)])
我需要做的是取from_array
的第一个条目并计算from_array[0]
到to_array中所有点之间的所有距离,然后保持最大距离。
所以我可以为此做好准备:
def get_distances(from_array, to_array):
results = []
distances = []
for pt in from_array:
for to in to_array:
results.append(calc_dist(pt, to))
distances.append(results)
return distances
但这很慢,我正在寻找一种优化的计算方法,因为我可以获得数千点。
最终目标是计算Hausdorff距离。
fhd = np.mean(np.min(SomeDistanceArray,axis=0))
rhd = np.mean(np.min(SomeDistanceArray,axis=1))
print (max(fhd, rhd))
我想使用numpy执行此任务仅。 我的距离可以是欧几里德或欧氏距离。
所以我正在寻求帮助的是一种优化的方法,用于计算两个np阵列的欧氏距离方法。应该注意的是,数组1可能比数组2有更多的行。意味着2D数组(x,y)的长度可以比较10行到30行。
答案 0 :(得分:4)
这是一个基于NumPy的方法np.einsum
-
subs = from_array[:,None] - to_array
sq_eucliean_dist = np.einsum('ijk,ijk->ij',subs,subs)
eucliean_dist = np.sqrt(sq_eucliean_dist)
注意:如果您稍后计算np.mean(np.min(SomeDistanceArray,axis=0))
,则可以跳过eucliean_dist
的计算并直接使用sq_eucliean_dist
作为SomeDistanceArray
,因为计算平方根会非常昂贵。
np.einsum('ijk,ijk->ij',subs,subs)
做了什么?它在同一个数组subs
之间执行元素乘法,即基本上是平方,然后沿最后一个轴进行求和,从而丢失它在那个减少过程中。
那么,为什么不明确地进行平方和求和呢?嗯,np.einsum
的好处是它一步完成平方和求和,给我们显着的性能效率。
因此,最后如果from_array
是(N x 2)
数组而to_array
是(M x 2)
数组,则np.einsum
的输出将是欧氏距离的平方作为2D形状数组(N x M)
。
关于字符串表示法本身的更多信息将涉及更长时间的讨论,其中一些可以在this post
和之前发布的官方文档链接中找到。
答案 1 :(得分:1)
仅限Numpy。所以没有scipy.spatial.distance.cdist
首先,不要使用元组,使用2xN和2xM阵列。然后广播。
np.linalg.norm(from_array[:,:,None]-to_array[:,None,:], axis=0)
如果你有一个古老版本的numpy而没有一个可升级的linalg.norm
(即你正在使用Abaqus),请执行以下操作:
np.sum((from_array[:,:,None]-to_array[:,None,:])**2, axis=0).__pow__(0.5)