gpt4 book ai didi

python - Numpy:找到两个 3-D 数组之间的欧氏距离

转载 作者:太空狗 更新时间:2023-10-30 02:27:37 25 4
gpt4 key购买 nike

给定两个维度为 (2,2,2) 的 3-D 数组:

A = [[[ 0,  0],
[92, 92]],

[[ 0, 92],
[ 0, 92]]]

B = [[[ 0, 0],
[92, 0]],

[[ 0, 92],
[92, 92]]]

如何有效地找到 A 和 B 中每个向量的欧氏距离?

我已经尝试过 for 循环,但它们很慢,而且我正在按照 (>>2, >>2, 2) 的顺序处理 3-D 数组。

最终我想要一个如下形式的矩阵:

C = [[d1, d2],
[d3, d4]]

编辑:

我尝试了以下循环,但最大的问题是失去了我想要保留的维度。但是距离是正确的。

[numpy.sqrt((A[row, col][0] - B[row, col][0])**2 + (B[row, col][1] -A[row, col][1])**2) for row in range(2) for col in range(2)]

最佳答案

以 NumPy 向量化方式思考,即执行逐元素微分、沿最后一个轴求平方和求和,最后求平方根。因此,直接的实现方式是 -

np.sqrt(((A - B)**2).sum(-1))

我们可以用 np.einsum 一次性沿着最后一个轴进行平方和求和。从而使它更有效率,就像这样 -

subs = A - B
out = np.sqrt(np.einsum('ijk,ijk->ij',subs,subs))

另一种选择 numexpr module -

import numexpr as ne
np.sqrt(ne.evaluate('sum((A-B)**2,2)'))

因为我们正在处理沿最后一个轴的长度 2,我们可以将它们切片并将其提供给 evaluate 方法。请注意,在求值字符串中不可能进行切片。因此,修改后的实现将是 -

a0 = A[...,0]
a1 = A[...,1]
b0 = B[...,0]
b1 = B[...,1]
out = ne.evaluate('sqrt((a0-b0)**2 + (a1-b1)**2)')

运行时测试

函数定义-

def sqrt_sum_sq_based(A,B):
return np.sqrt(((A - B)**2).sum(-1))

def einsum_based(A,B):
subs = A - B
return np.sqrt(np.einsum('ijk,ijk->ij',subs,subs))

def numexpr_based(A,B):
return np.sqrt(ne.evaluate('sum((A-B)**2,2)'))

def numexpr_based_with_slicing(A,B):
a0 = A[...,0]
a1 = A[...,1]
b0 = B[...,0]
b1 = B[...,1]
return ne.evaluate('sqrt((a0-b0)**2 + (a1-b1)**2)')

时间 -

In [288]: # Setup input arrays
...: dim = 2
...: N = 1000
...: A = np.random.rand(N,N,dim)
...: B = np.random.rand(N,N,dim)
...:

In [289]: %timeit sqrt_sum_sq_based(A,B)
10 loops, best of 3: 40.9 ms per loop

In [290]: %timeit einsum_based(A,B)
10 loops, best of 3: 22.9 ms per loop

In [291]: %timeit numexpr_based(A,B)
10 loops, best of 3: 18.7 ms per loop

In [292]: %timeit numexpr_based_with_slicing(A,B)
100 loops, best of 3: 8.23 ms per loop

In [293]: %timeit np.linalg.norm(A-B, axis=-1) #@dnalow's soln
10 loops, best of 3: 45 ms per loop

关于python - Numpy:找到两个 3-D 数组之间的欧氏距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40319433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com