例如,我有一个尺寸为(N,M)的二维数组Y:
N, M = 200, 100
Y = np.random.normal(0,1,(N,M))
对于每个N,我想计算向量(M,1)及其转置的点积,这将返回一个(M,M)矩阵。一种低效的方法是:
Y = Y[:,:,np.newaxis]
[Y[i,:,:] @ Y[i,:,:].T for i in range(N)]
这非常慢:第二行的timeit返回
11.7 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
我认为一种更好的方法是使用einsum numpy函数(https://docs.scipy.org/doc/numpy/reference/generated/numpy.einsum.html):
np.einsum('ijk,imk->ijm', Y, Y, optimize=True)
((意味着:对于第i行,创建一个(j,k)矩阵,其元素来自最后一个维度m上的点积)
这两个方法确实返回了完全相同的结果,但是此新版本的运行时令人失望(仅比速度快一倍多)
3.82 ms ± 146 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
由于第一种方法效率不高,因此使用向量化einsum函数会带来更多改进。您对此有一个解释吗?是否有更好的方法进行此计算?
我有一个尺寸为(N,M)的二维数组Y,例如:N,M = 200,100 Y = np.random.normal(0,1,(N,M))对于每个N,我想计算向量(M,1)与其转置的点积,...In [60]: N, M = 200, 100
...: Y = np.random.normal(0,1,(N,M))
In [61]: Y1 = Y[:,:,None]