Python 为什么矢量化的Pinv比未矢量化的慢?
我有十个Python 为什么矢量化的Pinv比未矢量化的慢?,python,numpy,vectorization,Python,Numpy,Vectorization,我有十个6000 x 784矩阵。如果我在每个设备上运行np.cov,然后运行pinv,则总时间为: %timeit for n in range(10): pinv(np.cov(A,rowvar = False)) 1.64 s ± 78.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 如果我改为循环np.cov并计算3D堆栈的pinv,我得到: %timeit for n in range(10): dd[n] = np.c
6000 x 784
矩阵。如果我在每个设备上运行np.cov,然后运行pinv,则总时间为:
%timeit for n in range(10): pinv(np.cov(A,rowvar = False))
1.64 s ± 78.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
如果我改为循环np.cov并计算3D堆栈的pinv,我得到:
%timeit for n in range(10): dd[n] = np.cov(A,rowvar = False)
485 ms ± 18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit pinv(dd)
4.59 s ± 369 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
为什么3D上的pinv这么慢
如何计算堆栈的np.cov和相应的pinv?这取决于实现。限制步骤是numpy
matmul
。首先,我认为SVD是一个限制步骤,但它是线性扩展的(每次迭代约130毫秒,十人一组1.3秒)
以下是分析的一些部分:
1个呼叫(您的第一个代码片段)
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.1310.1310.1310.131Linalg.py:1299(svd)
1 0.0110.0110.0110.011{内置方法numpy.core.multiarray.matmul}
1 0.003 0.003 0.144 0.144:1(pinv)
10人一组的1次调用(您的第二个代码片段)
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 2.952 2.952 2.952 2.952{内置方法numpy.core.multiarray.matmul}
1 1.265 1.265 1.265 1.265 linalg.py:1299(svd)
1 0.026 0.026 4.266 4.266:1(品脱)
也许C-ordering有一个内部问题(但最近的numpy版本应该会解决这个问题),或者在这种情况下它效率很低。。。尝试使用直接更改为BLAS接口,但这仅在二维矩阵上操作。实际上已经提出了这些问题(matmul的速度很慢)
底线是,非矢量化或尝试使用其他实现。有时矩阵乘法的快速方法是使用特征函数
,但我从未在多维问题中尝试过
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.131 0.131 0.131 0.131 linalg.py:1299(svd)
1 0.011 0.011 0.011 0.011 {built-in method numpy.core.multiarray.matmul}
1 0.003 0.003 0.144 0.144 <ipython-input-76-2a63f1c84429>:1(pinv)
ncalls tottime percall cumtime percall filename:lineno(function)
1 2.952 2.952 2.952 2.952 {built-in method numpy.core.multiarray.matmul}
1 1.265 1.265 1.265 1.265 linalg.py:1299(svd)
1 0.026 0.026 4.266 4.266 <ipython-input-76-2a63f1c84429>:1(pinv)