问题更侧重于计算的性能。
我有 2 个矢量矩阵。这意味着它们对于 X、Y、Z 具有 3 个深度维度。矩阵的每个元素都必须与另一个矩阵相同位置的元素进行点积。
一个简单而低效的代码将是这个:
import numpy as np
a = np.random.uniform(low=-1.0, high=1.0, size=(1000,1000,3))
b = np.random.uniform(low=-1.0, high=1.0, size=(1000,1000,3))
c = np.zeros((1000,1000))
numRow,numCol,numDepth = np.shape(a)
for idRow in range(numRow):
for idCol in range(numCol):
# Angle in radians
c[idRow,idCol] = math.acos(a[idRow,idCol,0]*b[idRow,idCol,0] + a[idRow,idCol,1]*b[idRow,idCol,1] + a[idRow,idCol,2]*b[idRow,idCol,2])
但是,numpy 函数可以加快计算速度,如下所示,使代码更快:
# Angle in radians
d = np.arccos(np.multiply(a[:,:,0],b[:,:,0]) + np.multiply(a[:,:,1],b[:,:,1]) + np.multiply(a[:,:,2],b[:,:,2]))
但是,我想知道是否有其他的 sintaxis 可以通过其他函数、索引等来改进上面的这个
第一个代码耗时 4.658s 而第二个代码耗时 0.354s
请您参考如下方法:
您可以使用 np.einsum 执行此操作,它在任何轴上相乘然后求和:
np.arccos(np.einsum('ijk,ijk->ij', a, b))
完成您在问题中发布的内容的更直接的方法是使用 np.sum,您可以沿最后一个轴 (-1) 求和:
np.arccos(np.sum(a*b, -1))
它们都给出了相同的答案,但 einsum 是最快的,sum 次之:
In [36]: timeit np.arccos(np.einsum('ijk,ijk->ij', a, b))
10000 loops, best of 3: 20.4 µs per loop
In [37]: timeit e = np.arccos(np.sum(a*b, -1))
10000 loops, best of 3: 29.8 µs per loop
In [38]: %%timeit
....: d = np.arccos(np.multiply(a[:,:,0],b[:,:,0]) +
....: np.multiply(a[:,:,1],b[:,:,1]) +
....: np.multiply(a[:,:,2],b[:,:,2]))
....:
10000 loops, best of 3: 34.6 µs per loop
