Python 向量化大整数乘法

Python 向量化大整数乘法,python,arrays,numpy,vectorization,multiplication,Python,Arrays,Numpy,Vectorization,Multiplication,我对计算一个大的NumPy数组感兴趣。我有一个大数组a,其中包含一组数字。我想计算这些数字不同组合的总和。数据结构如下: A = np.random.uniform(0,1, (3743, 1388, 3)) Combinations = np.random.randint(0,3, (306,3)) Final_Product = np.array([ np.sum( A*cb, axis=2) for cb in Combinations]) 我的问题是,是否有一种更优雅、更节省内存的

我对计算一个大的NumPy数组感兴趣。我有一个大数组
a
,其中包含一组数字。我想计算这些数字不同组合的总和。数据结构如下:

A = np.random.uniform(0,1, (3743, 1388, 3))
Combinations = np.random.randint(0,3, (306,3))
Final_Product = np.array([  np.sum( A*cb, axis=2)  for cb in Combinations])
我的问题是,是否有一种更优雅、更节省内存的方法来计算它?当涉及到三维数组时,我发现使用
np.dot()
很令人沮丧

如果有帮助,理想情况下,
最终产品的形状应该是(37433061388)。目前,
最终产品的形状是(30637431388),所以我可以通过重塑来达到目的。

不会提供所需的输出,除非您涉及可能包括
重塑的额外步骤。这里有一个
矢量化的
方法,使用它一次完成,无需任何额外的内存开销-

Final_Product = np.einsum('ijk,lk->lij',A,Combinations)
为了完整起见,这里有前面讨论过的
np.dot
重塑
-

M,N,R = A.shape
Final_Product = A.reshape(-1,R).dot(Combinations.T).T.reshape(-1,M,N)
运行时测试并验证输出-

In [138]: # Inputs ( smaller version of those listed in question )
     ...: A = np.random.uniform(0,1, (374, 138, 3))
     ...: Combinations = np.random.randint(0,3, (30,3))
     ...: 

In [139]: %timeit np.array([  np.sum( A*cb, axis=2)  for cb in Combinations])
1 loops, best of 3: 324 ms per loop

In [140]: %timeit np.einsum('ijk,lk->lij',A,Combinations)
10 loops, best of 3: 32 ms per loop

In [141]: M,N,R = A.shape

In [142]: %timeit A.reshape(-1,R).dot(Combinations.T).T.reshape(-1,M,N)
100 loops, best of 3: 15.6 ms per loop

In [143]: Final_Product =np.array([np.sum( A*cb, axis=2)  for cb in Combinations])
     ...: Final_Product2 = np.einsum('ijk,lk->lij',A,Combinations)
     ...: M,N,R = A.shape
     ...: Final_Product3 = A.reshape(-1,R).dot(Combinations.T).T.reshape(-1,M,N)
     ...: 

In [144]: print np.allclose(Final_Product,Final_Product2)
True

In [145]: print np.allclose(Final_Product,Final_Product3)
True

您可以使用。您当前的方法相当于:

np.tensordot(A, Combinations, [2, 1]).transpose(2, 0, 1)
注意末尾的
转置
,将轴按正确顺序排列


dot
一样,
tensordot
函数可以调用fast BLAS/LAPACK库(如果您安装了它们),因此对于大型阵列应该可以很好地执行。

谢谢!我还发现@ajcr的答案非常有用。我使用张量将
np.einsum
@Julien中使用的时间减半,我也喜欢ajcr的解决方案!我认为这是
dot
在这里所做的一个简洁版本。简短而简单,我喜欢@迪瓦卡:谢谢!我还是喜欢
einsum
不过:-)我也是!!当
einsum
推出一个3D数组时,我有这样的感觉,它不如简化为
2D
数组或最好是
标量数组那样有效。