python - 不同形状数组的Numpy距离计算

标签 python arrays numpy scipy euclidean-distance

不确定我的标题是否合适,但基本上我有一个引用坐标,格式为 (x,y,z),还有一个大的坐标列表/数组也采用该格式。我需要得到每个之间的欧几里得距离,所以理论上我应该能够使用 numpy 和 scipy 进行操作,例如:

import numpy, scipy.spatial.distance
a = numpy.array([1,1,1])
b = numpy.random.rand(20,3)

distances = scipy.spatial.distance.euclidean(b, a)

但我没有返回数组,而是收到错误:ValueError: Input vector should be 1-D.

不确定如何解决此错误并获得我想要的结果而不必诉诸循环等,这违背了使用 Numpy 的目的。

从长远来看,我想使用这些距离来计算用于计算 bin 中的距离值的真值掩码。

我不确定我只是使用了错误的功能还是使用了错误的功能,我无法在文档中找到任何可以更好地工作的内容。

最佳答案

documentation scipy.spatial.distance.euclidean 声明,仅允许一维向量作为输入。因此,您必须像这样遍历数组:

distances = np.empty(b.shape[0])
for i in range(b.shape[0]):
    distances[i] = scipy.spatial.distance.euclidean(a, b[i])

如果你想有一个向量化的实现,你需要自己写一个函数。或许使用具有正确签名的 np.vectorize 也能奏效,但这实际上也只是 for 循环的简写形式,因此具有与简单 for 循环相同的性能。

正如我在对 hannes wittingham 的解决方案的评论中所述,我将发布一个专注于性能的单行代码:

distances = ((b - a)**2).sum(axis=1)**0.5

写出所有计算减少了单独函数调用的次数,从而减少了将中间结果分配给新数组的次数。因此,对于 b.shape == (20, 3) 的数组形状,它比使用 hannes wittingham 的解决方案快约 22%,对于数组形状的数组形状快约 5% b.shape == (20000, 3):

a = np.array([1, 1, 1,])
b = np.random.rand(20, 3)
%timeit ((b - a)**2).sum(axis=1)**0.5
# 5.37 µs ± 140 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit euclidean_distances(a, b)
# 6.89 µs ± 345 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

b = np.random.rand(20000, 3)
%timeit ((b - a)**2).sum(axis=1)**0.5
# 588 µs ± 43.2 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit euclidean_distances(a, b)
# 616 µs ± 36.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

但是您正在失去能够轻松更改为距离计算例程的灵 active 。使用 scipy.spatial.distance 模块时,您可以通过简单地调用另一个方法来更改计算路由。

为了进一步提高计算性能,您可以为您的函数使用像 numba 这样的 jit(即时)编译器:

import numba as nb
@nb.njit
def euc(a, b):
    return ((b - a)**2).sum(axis=1)**0.5

这将小型阵列的计算时间减少了大约 70%,大型阵列的计算时间减少了大约 60%。不幸的是,numba 尚不支持 np.linalg.normaxis 关键字。

关于python - 不同形状数组的Numpy距离计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51250169/

相关文章:

python - Pandas 数组长度与索引长度不匹配,每周有效但每月无效?

python - 使用 numpy 逐像素计算栅格的平均值

python - 从 python 数组中选择行

Python3 如何检查一个项目是否已经在txt文件中

python - Pandas 数据框 - 使用 np.clip() 设置边界并从列中的特定值中减去值

javascript - 数组附加项未进行到结帐

python - 使用滑动窗口和转置进行分组

python - 将其他 Python 脚本作为模块导入

python - 来自嵌套字典的 Pandas 数据框将 dict 键添加到自己的列

ios - 如何使用与 NewtonSoft (JSON.Net) 组件中的 JSON 匹配的 Swift 类从 JSON 读取/写入对象数组?