给出一组存储在(n,d)数组中的维度为 d 的 n 个向量,以及第二组我想计算相同尺寸的m 个向量(存储在(m,d)数组中),计算向量之间的平方点方均距离,并由一些矩阵A缩放,其大小为(d,d)。
输出应为(n,m)数组。
我希望 m 和 n 的输入范围在1到10.000之间,而 d 的输入范围在1到100之间。
两点之间的距离由下式给出:
在未优化但有效的python代码中,该代码如下所示:
import numpy as np
v1 = np.array([[1, 2],
[3, 4],
[4, 5]])
v2 = np.array([[1,1],
[2, 2],
[2, 2],
[0, 0]])
A = np.array([[1,0], [2, 3]])
d = np.zeros((3, 4))
for i in range(0,3):
for j in range(0,4):
d[i,j] = (v1[i,:] - v2[j,:]).T @ A @ (v1[i,:] - v2[j,:])
示例点之间的平方距离是:
d = [[ 3. 1. 1. 17.]
[ 43. 17. 17. 81.]
[ 81. 43. 43. 131.]]
是否有此版本,可避免python中的嵌套循环,例如使用广播黑魔法?
编辑:
视情况
A = np.array([[1,0], [0, 1]])
这是可以计算出的正常平方欧几里德距离
from scipy.spatial.distance import cdist
cdist(v1,v2,'sqeuclidean')
答案 0 :(得分:1)
我们可以使用np.einsum
-
V = v1[:,None,:]-v2
d_out = np.einsum('ijk,kl,ijl->ij',V,A,V)
另外,通过将其设置为optimize
以使用BLAS,在np.einsum
中使用True
标志。
向量化方法的说明
原始代码为-
d[i,j] = (v1[i,:] - v2[j,:]).T @ A @ (v1[i,:] - v2[j,:])
I。我们正在翻译:
v1[i,:] - v2[j,:]
使用broadcasting
进行外部操作:
v1[:,None,:]-v2
示意性地放在:
v1[:,None,:] : m x 1 x n
v2 : m x n
output, V : m x m x n
More info on outer
explanation.
可以在docs
中找到有关broadcasting
的更多信息。
II。接下来,使用(v1[i,:] - v2[j,:]).T @ A @ (v1[i,:] - v2[j,:])
的字符串符号将带有新V
的{{1}}变成np.einsum('ijk,kl,ijl->ij',V,A,V)
。可以在docs
中找到更多信息。