numpy 计算矩阵的行方向“v.T @ v”和的最快方法

57hvy0tb  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(86)

我有一个1000 x 500的矩阵。对于每一行,我想计算行向量的转置和行向量本身(应该是标量)之间的点积,并对所有行求和。现在我正在使用

import numpy as np

A = np.random.random((1000, 500))
res = sum(A[i].T @ A[i] for i in range(A.shape[0]))

由于这是我的算法的性能瓶颈,我想知道是否有更快的方法来做到这一点,最好是Numpyic解决方案。

gywdnpxw

gywdnpxw1#

测试hpaulj问题注解中的答案。添加简单的替代-np.sum(A**2)和两个numba函数:单CPU和并行。
TLDR:最快的是sum_of_squares_numba_parallel功能。最快的numpy唯一解决方案:np.einsum('ij,ij',A,A)

@numba.jit("float64(float64[:,:])")
def sum_of_squares_numba(a):
    sum = 0
    n_y, n_x = a.shape
    for i in range(n_y):
        for j in range(n_x):
            sum += a[i, j] * a[i, j]

    return sum

@numba.jit("float64(float64[:, :])", parallel=True)
def sum_of_squares_numba_parallel(a):
    sum = 0
    n_rows, n_cols = a.shape
    for i in numba.prange(n_rows):
        for j in range(n_cols):
            sum += a[i, j] * a[i, j]
    return sum

使用line profiler的粗略计时显示,np.einsum('ij,ij',A,A)在numpy only结果方面显然是赢家。可能是因为它不必在内存中创建迭代A*A结果,然后访问它来计算sum。
Numba单CPU计算也不远了,也许可以做得更好。
sum_of_squares_numba_parallel是目前最快的版本。在我的机器上比einsum快3-4倍。

相关问题