我想在Python中高效地计算一个矩阵,该矩阵包含来自两个单独数组的所有向量对的余弦。它将是形状为(M,N)
的矩阵A,而所考虑的向量是2-D [x, y]
ndarrays,因此包含它们的阵列的形状为(M,2)
和(N,2)
:
u = [u0, ..., uM]
v = [v0, ..., vN]
A = [[cos(u0,v0), cos(u0,v1), .... ],
...
[... .., cos(uM,vN)]]
这是一个非常简单的代码,有一个for
循环,但在我的例子中,它被调用了很多次,我希望通过使用向量化的方式来提高我的算法的性能,理想情况下使用numpy数组,但我愿意接受建议。
我尝试通过使用np.meshgrid()
创建一个矩阵来实现这个结果,但它给出了二维向量的奇怪结果(形状列表(6,4)而不是(3,2)):
AC_vectors = np.array([[69., 40.],[187.3, 35.], [12., 80]])
AB_vectors = np.array([[22., 150.],[42.5, 20.7]])
np.meshgrid(AB_vectors, AC_vectors)
[array([[ 22. , 150. , 42.5, 20.7],
[ 22. , 150. , 42.5, 20.7],
[ 22. , 150. , 42.5, 20.7],
[ 22. , 150. , 42.5, 20.7],
[ 22. , 150. , 42.5, 20.7],
[ 22. , 150. , 42.5, 20.7]]), array([[ 69. , 69. , 69. , 69. ],
[ 40. , 40. , 40. , 40. ],
[187.3, 187.3, 187.3, 187.3],
[ 35. , 35. , 35. , 35. ],
[ 12. , 12. , 12. , 12. ],
[ 80. , 80. , 80. , 80. ]])]
而对于对象(因此输入数组是一维数组),它的行为符合预期:
AB_vectors = [Vector(x,y) for x,y in[[22., 150.], [42.5, 20.7]]]
AC_vectors = [Vector(x,y) for x,y in[[69., 40.], [187.3, 35.], [12., 80]]]
np.meshgrid(AB_vectors, AC_vectors)
[array([[Vector(x=22.0, y=150.0), Vector(x=42.5, y=20.7)],
[Vector(x=22.0, y=150.0), Vector(x=42.5, y=20.7)],
[Vector(x=22.0, y=150.0), Vector(x=42.5, y=20.7)]], dtype=object), array([[Vector(x=69.0, y=40.0), Vector(x=69.0, y=40.0)],
[Vector(x=187.3, y=35.0), Vector(x=187.3, y=35.0)],
[Vector(x=12.0, y=80), Vector(x=12.0, y=80)]], dtype=object)]
我当时希望使用余弦向量化版本的点积和范数来计算矩阵,但我找不到一种有效的方法来绕过meshgrid()来生成[ui,vj]
对矩阵。
理想情况下,将存在直接生成矩阵的方法,而无需首先创建所有可能对的矩阵。
2条答案
按热度按时间3b6akqbq1#
如果你想得到向量之间的成对余弦,你可以直接使用公式,而不需要(显式地)生成每一对。计算的成对分量表示为矩阵乘法。
矩阵的(i,j)单元包含第i个向量和第j个向量的余弦相似性。
liwlm1x92#
您可以创建索引的网格,然后使用它创建所有组合。从那里,你可以计算点积,并除以范数得到向量之间的Angular 的余弦。