Search code examples
pythonnumpybroadcast

How to multiply individual elements of numpy array of row ith with element of another numpy array of row ith?


How to multiply individual elements of numpy array of row ith with element of another numpy array of row ith?

The inventory example is that I want to multiply an numpy array(containing the item's (280 of them) costing in USD, Euro) of size [280,2] with an numpy array of size [280,3] (stocks in 3 store houses(representing the column).

I believe I have no problem using for loops to calculate but I am trying to learn techniques of broadcasting and reshape. So I would like your help to point me the correct direction(or methods)

Edit: Example

  Array A            
  [[1.50 1.80]        
  [3    8   ]]        

  Array B
  [[5  10 20]
  [10 20 30]]

Result I require is

  [[7.5 9  11.5 18  30 36]
  30  80 60   160 90  240]]

Thanks


Solution

  • The description was a bit fuzzy, as was the example:

    In [264]: A=np.array([[1.5,1.8],[3,8]]); B=np.array([[5,10,20],[10,20,30]])                          
    In [265]: A.shape                                                                                    
    Out[265]: (2, 2)
    In [266]: B.shape                                                                                    
    Out[266]: (2, 3)
    

    Looks like you are trying to do a version of outer product, which can be done with broadcasting.

    Let's try one combination:

    In [267]: A[:,:,None]*B[:,None,:]                                                                    
    Out[267]: 
    array([[[  7.5,  15. ,  30. ],
            [  9. ,  18. ,  36. ]],
    
           [[ 30. ,  60. ,  90. ],
            [ 80. , 160. , 240. ]]])
    

    The right numbers are there, but not the right order. Let's try again:

    In [268]: A[:,None,:]*B[:,:,None]                                                                    
    Out[268]: 
    array([[[  7.5,   9. ],
            [ 15. ,  18. ],
            [ 30. ,  36. ]],
    
           [[ 30. ,  80. ],
            [ 60. , 160. ],
            [ 90. , 240. ]]])
    

    That's better - now just reshape:

    In [269]: _.reshape(2,6)                                                                             
    Out[269]: 
    array([[  7.5,   9. ,  15. ,  18. ,  30. ,  36. ],
           [ 30. ,  80. ,  60. , 160. ,  90. , 240. ]])
    

    _268 is a partial transpose of _267, .transpose(0,2,1).