在一个numpy数组中相乘

我试图用二维数组中的每个项乘以一维数组中的相应项。 如果我想用1D数组乘以每一列,这很容易,如numpy.multiply函数所示。 但是我想做相反的事情,把每一个词汇都放在一行中。 换句话说,我想要繁殖:

[1,2,3] [0] [4,5,6] * [1] [7,8,9] [2] 

并得到

 [0,0,0] [4,5,6] [14,16,18] 

但是我得到了

 [0,2,6] [0,5,12] [0,8,18] 

有谁知道是否有一个优雅的方式来做到这一点与numpy? 亚历克斯,谢谢

像你这样的正常乘法表明:

 >>> import numpy as np >>> m = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> c = np.array([0,1,2]) >>> m * c array([[ 0, 2, 6], [ 0, 5, 12], [ 0, 8, 18]]) 

如果你添加一个轴,它将会以你想要的方式相乘:

 >>> m * c[:, np.newaxis] array([[ 0, 0, 0], [ 4, 5, 6], [14, 16, 18]]) 

你也可以转置两次:

 >>> (mT * c).T array([[ 0, 0, 0], [ 4, 5, 6], [14, 16, 18]]) 

你也可以使用matrix乘法(又名点积):

 a = [[1,2,3],[4,5,6],[7,8,9]] b = [0,1,2] c = numpy.diag(b) numpy.dot(c,a) 

更优雅的可能是品味的问题。

还有一个技巧(截至v1.6)

 A=np.arange(1,10).reshape(3,3) b=np.arange(3) np.einsum('ij,i->ij',A,b) 

我熟练掌握numpy广播( newaxis ),但我仍然find了解决这个新的工具的方法。 所以我玩了一下find这个解决scheme。

计时(使用Ipython timeit):

 einsum: 4.9 micro transpose: 8.1 micro newaxis: 8.35 micro dot-diag: 10.5 micro 

顺便说一句,将i改为jnp.einsum('ij,j->ij',A,b)产生Alex不想要的matrix。 而np.einsum('ji,j->ji',A,b)实际上是双转置。

我比较了不同的速度选项,发现 – 令我惊讶的是 – 所有选项( diag除外)同样快:

在这里输入图像说明


代码重现情节:

 import numpy import perfplot def newaxis(data): A, b = data return A * b[:, numpy.newaxis] def double_transpose(data): A, b = data return (AT * b).T def double_transpose_contiguous(data): A, b = data return numpy.ascontiguousarray((AT * b).T) def diag_dot(data): A, b = data return numpy.dot(numpy.diag(b), A) def einsum(data): A, b = data return numpy.einsum('ij,i->ij', A, b) perfplot.show( setup=lambda n: (numpy.random.rand(n, n), numpy.random.rand(n)), kernels=[ newaxis, double_transpose, double_transpose_contiguous, diag_dot, einsum ], n_range=[2**k for k in range(10)], logx=True, logy=True, xlabel='len(A), len(b)' ) 

你为什么不这样做?

 >>> m = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> c = np.array([0,1,2]) >>> (mT * c).T 

??