如何使用向量化计算距离矩阵

3
我有一个numpy数组A,形状为4 X 3 X 2。每行下面都是一个节点的二维坐标。(在我的有限元分析中,每三个节点组成一个三角形。)
array([[[0., 2.],  #node00 
        [2., 2.],  #node01
        [1., 1.]], #node02

       [[0., 2.],  #node10
        [1., 1.],  #node11
        [0., 0.]], #node12

       [[2., 2.],  #node20
        [1., 1.],  #node21
        [2., 0.]], #node22

       [[0., 0.], #node30
        [1., 1.], #node31
        [2., 0.]]]) #node32

我有另一个numpy数组B,其中包含预先计算的“中心”坐标:

array([[1.        , 1.66666667], # center0
       [0.33333333, 1.        ], # center1
       [1.66666667, 1.        ], # center2
       [1.        , 0.33333333]])# center3

我该如何高效地计算类似这样的欧几里得距离矩阵 C
dist(center0, node00) dist(center0,node01) dist(center0, node02)
dist(center1, node10) dist(center1,node11) dist(center1, node12)
dist(center2, node20) dist(center2,node21) dist(center2, node22)
dist(center3, node30) dist(center3,node31) dist(center3, node32)

其中dist代表欧几里德距离公式,例如math.dist或numpy.linalg.norm?即结果矩阵的i,j元素是从中心i到节点ij的距离。

需要使用向量化代码而不是循环,因为我的实际数据来自非常大的医学成像。通过嵌套循环,可以获得预期的输出,如下所示:

In [63]: for i in range(4):
    ...:     for j in range(3):
    ...:         C[i,j]=math.dist(A[i,j], B[i]) 

In [67]: C
Out[67]:
array([[1.05409255, 1.05409255, 0.66666667],
       [1.05409255, 0.66666667, 1.05409255],
       [1.05409255, 0.66666667, 1.05409255],
       [1.05409255, 0.66666667, 1.05409255]])

[编辑] 这是一个不同的问题,与numpy中两个列表的成对操作(距离)不同,因为这里需要正确处理索引。


这回答您的问题吗?在numpy中对两个列表进行成对操作(距离)。您的数据已经以数组形式存在并不太重要;那里展示的功能应该能满足您的所有需求。我想您可能只是缺少可轻易搜索的"pairwise distance"关键字 :) - Dominik Stańczak
1
使用广播,将 np.linalg.norm(A - B[:, None], axis=-1) 进行计算。 - Michael Szczesny
1个回答

3
a = np.reshape(A, [12, 2])
b = B[np.repeat(np.arange(4), 3)]
c = np.reshape(np.linalg.norm(a - b, axis=-1), (4, 3))
c
# array([[1.05409255, 1.05409255, 0.66666667],
#        [1.05409255, 0.66666667, 1.05409255],
#        [1.05409255, 0.66666667, 1.05409255],
#        [1.05409255, 0.66666667, 1.05409255]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接