使用Numpy的高效行产品



我有以下代码来获取两个不同 Numpy 数组的行的乘法。我也将结果与 Numba 进行了比较:

import numpy as np
from numba import jit
from itertools import product    
from time import time

@jit( nopython=True)
def numba_product(a,b):
a_len = len(a)
b_len = len(b)
n     = len( a[0,:] )
c_res   = np.empty( (  a_len*b_len, n ), dtype=np.complex128 ) 
c_count = 0  
for i in range(a_len):
for j in prange( b_len ):            
c_res[ c_count , : ] = np.multiply( a[i,:], b[ j, : ]  )          
c_count += 1

return c_res
n= 100
iu = np.complex(0,1)
a = np.random.rand( n, 300 ) + iu*np.random.rand( n, 300 )
b = np.random.rand( n, 300 ) + iu*np.random.rand( n, 300 )

time_start = time()
c =  np.array( [ np.multiply( x[0],x[1] ) for x in  product( a,b ) ] )
time_end   = time()
print("--> time is %8.7f secs" % (time_end - time_start) )
c_r = numba_product( a,b )
time_start = time()
c_r = numba_product( a,b )
time_end   = time()
print("--> time is %8.7f secs" % (time_end - time_start) )

我知道必须在 Numpy 中实现这一点,这是以更有效的方式吗?谢谢!

编辑:我只是使用了建议的答案,并找到了以下执行时间("a"和"b"数组的形状是(100,300((:

Itertools product + generator  --> 0.0712414 seconds 
Numba loops                    --> 0.0353553 seconds
index multiplication           --> 0.0302799 seconds

所以似乎有一些~14%左右的改进,谢谢!

In [54]: from itertools import product                                                  
In [55]: c =  np.array( [ np.multiply( x[0],x[1] ) for x in  product( a,b ) ] )         
In [56]: c.shape                                                                        
Out[56]: (10000, 300)

看起来您正在第一个维度上做外部产品 - 扁平化

In [57]: a.shape                                                                        
Out[57]: (100, 300)
In [58]: b.shape                                                                        
Out[58]: (100, 300)
In [59]: np.allclose((a[:,None,:]*b[None,:,:]).reshape(-1,300),c) 
Out[59]: True

我会让你做比较时间

当你做这样的计时时,礼貌的做法是展示印刷品,计时结果。 这样我们就不必自己运行事情了。 关于结果的一些信息,例如形状。

最新更新