我有两个矩阵:
A = [a11 a12
a21 a22]
B = [b11 b12
b21 b22]
我想将所有列(没有循环)相乘以获得矩阵:
C =[a11*b11 a11*b12 a12*b11 a12*b12
a21*b21 a21*b22 a22*b21 a22*b22]
我已经尝试了
>>> C = np.prod(A,B,axis=0)
但是prod不接受两个输入矩阵。既不是np.matrix.prod。
提前致谢。
答案 0 :(得分:8)
我们可以使用broadcasting
作为矢量化解决方案 -
(A[...,None]*B[:,None]).reshape(A.shape[0],-1)
哲学:就矢量化/广播语言而言,我会将其描述为传播或将输入数组的第二维相互对立,同时保持它们的第一个尺寸对齐。这种传播是通过为这两个输入引入None/np.newaxis
的新轴来完成的,然后简单地相互相乘。
数学观点:在通用示例的帮助下,让我们使用更多的数学视图。考虑具有不同列数的输入数组 -
In [504]: A = np.random.rand(2,3)
In [505]: B = np.random.rand(2,4)
首先,扩展尺寸并检查其形状 -
In [506]: A[...,None].shape
Out[506]: (2, 3, 1)
In [507]: B[:,None].shape
Out[507]: (2, 1, 4)
现在,执行逐元素乘法,它将以广播方式执行这些乘法。仔细看看输出的形状 -
In [508]: (A[...,None]*B[:,None]).shape
Out[508]: (2, 3, 4)
因此,使用None/np.newaxis
引入的单例维度(长度为1的维度)将是各个数组的元素在乘法之前在引擎盖下广播的那些维度。这种引擎盖下的广播与相应的操作(在这种情况下相乘)配对是以非常有效的方式完成的。
最后,我们将此3D
数组重新整形为2D
,使行数保持与原始输入的行数相同。
示例运行
In [494]: A
Out[494]:
array([[2, 3],
[4, 5]])
In [495]: B
Out[495]:
array([[12, 13],
[14, 15]])
In [496]: (A[...,None]*B[:,None]).reshape(A.shape[0],-1)
Out[496]:
array([[24, 26, 36, 39],
[56, 60, 70, 75]])
NumPy matrix
输入
对于NumPy matrix types
作为输入,我们可以使用np.asmatrix
来简单地创建输入视图。使用这些视图,将执行广播的逐元素乘法,最终在重新整形后产生2D
数组。因此,最后一步是转换回np.matrix
类型。让我们使用相同的示例输入来演示实现 -
In [553]: A
Out[553]:
matrix([[2, 3],
[4, 5]])
In [554]: B
Out[554]:
matrix([[12, 13],
[14, 15]])
In [555]: arrA = np.asarray(A)
In [556]: arrB = np.asarray(B)
In [557]: np.asmatrix((arrA[...,None]*arrB[:,None]).reshape(A.shape[0],-1))
Out[557]:
matrix([[24, 26, 36, 39],
[56, 60, 70, 75]])
答案 1 :(得分:1)
b = np.tile(B, 2) # two copies of B, side by side
a = np.tile(A, 2)
a = np.hstack((a[:,::2], a[:,1::2])) # change 1,2,1,2 to 1,1,2,2
a * b # done
我希望有更好的方法来完成第三步,但上述工作并且相对有效。