求两个向量之间每对的距离

问题描述 投票:0回答:2

我有两个向量,比如说

x=[2,4,6,7]
y=[2,6,7,8]
,我想找到每个对应对之间的欧几里得距离,或任何其他实现的距离(例如来自 scipy)。那将是
dist=[0, 2, 1, 1]

当我尝试时

dist = scipy.spatial.distance.cdist(x,y, metric='sqeuclidean')

dist = [scipy.spatial.distance.cdist(x,y, metric='sqeuclidean') for x,y in zip(x,y)]

我明白了

ValueError: XA must be a 2-dimensional array.

我应该如何计算 dist 以及为什么我必须为此目的重塑数据?

python scipy
2个回答
0
投票

cdist 不计算对应对之间的距离列表,而是计算所有对之间的距离矩阵。

np.linalg.norm((np.asarray(x)-np.asarray(y))[:, None], axis=1)

对于 n 维点之间的欧几里得距离,id 通常是如何写的;但如果您只处理一维点,则 elpres 建议的绝对差异会更简单。


0
投票
当您需要比较多对向量时,

cdist
特别有用。

如果您需要仅比较 1 个向量与 1 个向量,或 1 个向量与多个向量进行比较,

np.linalg.norm
会更快:

1 个向量与多个向量:

>>> x: [1000, 5]
>>> %timeit np.linalg.norm(x - x[0], axis=-1)
29.7 µs ± 3.61 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %timeit scipy.spatial.distance.cdist(x, x[[0]])
47.3 µs ± 4.8 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

注意,无论如何你都需要向

cdist
传递一个 2d 数组,这可以通过
x[[0]]

来实现

多个向量与多个向量:

>>> x: [1000, 5]
>>> y: [20, 5]

为此,numpy 有两种方法,循环和广播: 所有这些方法都会输出形状为

(x.shape[0], y.shape[0])

的二维数组
  1. 用较少的向量循环数组(即
    y.shape[0] < x.shape[0]
>>> %%timeit
... res = np.empty((x.shape[0], y.shape[0]))
... for i in range(y.shape[0]):
...    res[:, i] = np.linalg.norm(x - y[i], axis=-1)
745 µs ± 66.4 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
  1. 广播:
>>> %timeit np.linalg.norm(x[:, None] - y, axis=-1)
1.47 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

使用

cdist

>>> %timeit scipy.spatial.distance.cdist(x, y)
95.5 µs ± 5.9 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

好处是显而易见的。

正如已接受答案的评论中提到的,您可以通过更改 numpy 中的

ord
和 scipy 中的
metric
来使用任何指标。

© www.soinside.com 2019 - 2024. All rights reserved.