Multiply two matrix by columns with python

后端 未结 2 2090
猫巷女王i
猫巷女王i 2020-12-18 09:06

I have two matrix:

A = [a11 a12 

     a21 a22]


B = [b11 b12
     b21 b22]

And I want to multiply all its columns (without loops) in orde

相关标签:
2条回答
  • 2020-12-18 09:13

    We could use broadcasting for a vectorized solution -

    (A[...,None]*B[:,None]).reshape(A.shape[0],-1)
    

    Philosophy : In terms of vectorized/broadcasting language, I would describe this as spreading or putting the second dimension of the input arrays against each other, while keeping their first dimensions aligned. This spreading is done by introducing new axes with None/np.newaxis for these two inputs and then simply multiplying each other.

    Mathematical view : Let's use a bit more mathematical view of it with the help of a generic example. Consider input arrays having different number of columns -

    In [504]: A = np.random.rand(2,3)
    
    In [505]: B = np.random.rand(2,4)
    

    First off, extend the dimensions and check their shapes -

    In [506]: A[...,None].shape
    Out[506]: (2, 3, 1)
    
    In [507]: B[:,None].shape
    Out[507]: (2, 1, 4)
    

    Now, perform the element-wise multiplication, which will perform these multiplications in a broadcasted manner. Take a closer look at the output's shape -

    In [508]: (A[...,None]*B[:,None]).shape
    Out[508]: (2, 3, 4)
    

    So, the singleton dimensions (dimension with length = 1) introduced by the use of None/np.newaxis would be the ones along which elements of the respective arrays would be broadcasted under the hood before being multiplied. This under-the-hood broadcasting paired with the respective operation (multiplication in this case) is done in a very efficient manner.

    Finally, we reshape this 3D array to 2D keeping the number of rows same as that of the original inputs.

    Sample run :

    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 type as inputs

    For NumPy matrix types as the inputs, we could use np.asmatrix that would simply create view into the inputs. Using those views, the broadcasted element-wise multiplication would be performed, finally resulting in a 2D array after the reshaping. So, the last step would be to convert back to np.matrix type. Let's use the same sample inputs to demonstrate the implementation -

    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]])
    
    0 讨论(0)
  • 2020-12-18 09:15
    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
    

    I expect there is a better way to do the third step, but the above works and is relatively efficient.

    0 讨论(0)
提交回复
热议问题