【问题标题】:Multiply two matrix by columns with python用python将两个矩阵乘以列
【发布时间】:2017-04-04 21:36:39
【问题描述】:

我有两个矩阵:

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 都不是。

提前致谢。

【问题讨论】:

    标签: python numpy matrix vectorization


    【解决方案1】:

    我们可以将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]])
    

    【讨论】:

    • 很好奇,但是在使用 np.matrix() 定义上述二维矩阵并应用广播时 - 会出现错误 ValueError: shape too large to be a matrix.
    • @RomanPerekhrest 好吧,我假设是 NumPy 数组。也许我应该澄清一下。
    • @Divakar,我刚刚阅读了第一个 OP 的句子 I have two matrix:,因此从 np.matrix([[11, 12], [21, 22]]) 开始,但在测试您的方法时出错。无论如何,这可能是另一种情况
    • @RomanPerekhrest 添加了使其适用于 NumPy 矩阵类型输入所需的修改。
    • @Divakar 是否也可以对超过 2 个数组/矩阵执行此操作?
    【解决方案2】:
    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
    

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

    【讨论】:

    • 是否也可以对超过 2 个数组/矩阵执行此操作?
    • @Varlor:试试看,如果你不明白,请提出一个新问题并在此处链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 2018-02-23
    相关资源
    最近更新 更多