用python将两列矩阵乘以

时间:2016-11-21 13:12:38

标签: python numpy matrix vectorization

我有两个矩阵:

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。

提前致谢。

2 个答案:

答案 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

我希望有更好的方法来完成第三步,但上述工作并且相对有效。