Skip to main content
 首页 » 编程设计

python之2向量矩阵点积的性能

2025年05月04日36zhenyulu

问题更侧重于计算的性能。

我有 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