numpy-einsum与朴素的实现运行时性能比较

问题描述 投票:0回答:2

例如,我有一个尺寸为(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)与其转置的点积,...
python performance numpy dot
2个回答
1
投票
In [60]: N, M = 200, 100 ...: Y = np.random.normal(0,1,(N,M)) In [61]: Y1 = Y[:,:,None]

0
投票
[这是旧文章,但涵盖了许多细节:efficient outer product
© www.soinside.com 2019 - 2024. All rights reserved.