简体   繁体   中英

Python: Numpy Multiply each row of a array with each rows of another array

I know there has been some questions about this and it should be possible with broadcasting. But somehow I dont really get how broadcasting works with adding ann additional axis. There is a similar question where each column of one array is multiplied with each column of another array here: Multiply each column with each column . In my case I want to multiply each row of the 2d arrays against each other

I simply have a 3 dimensional array created as the triangular matrix:

matrix = np.tril(np.ones((3,3,3),dtype='bool'))

For simplification just look at the first two arrays:

matrix[:2]

[[[ True False False]
  [ True  True False]
  [ True  True  True]]

 [[ True False False]
  [ True  True False]
  [ True  True  True]]]

This should become:

[[[ True False False]
  [ True False False]
  [ True False False]]#First row of first array multiplied with each row of second array

 [[ True False False]
  [ True  True False]
  [ True  True False]]#Second row of first array multiplied with each row of second array

 [[ True False False]
  [ True  True False]
  [ True  True  True]]]#Third row of first array multiplied with each row of third array

I can achieve this with

matrix[0][None,...]*matrix[1][:,None])

But how can I do it for the whole matrix without looping and how is the broadcasting works? This should then result in an 3d array with 9 2d arrays.

EDIT

For detailed explanation of what this is all about and how the resulting array should look like. I have a number of categories, lets say 3. All of this 3 categories could have 4 states, every state consists of a bool array with 4 bool values for example(Could also be 10 categories with 100 states with 100 bool values). I now want a resulting array which i can index to. So for example I want the output of the multiplied states of all 3 categories and the 3 value of it. I would index to it with resultingArray[0,0,0,1] for the second bool value of the multiplication.

With a 3x4x4 array (3 caategories,4 states,4bool values) but for visualtization with numbers this would look like as follows:

cats = 3
values = 4

matrix = np.arange(48).reshape(cats,values,values)
matrix.shape


totalArray=np.zeros((values,values,values,values))
for row1 in range(len(matrix[0])):
    for row2 in range(len(matrix[1])):
        for row3 in range(len(matrix[2])):
            totalArray[row1,row2,row3] = matrix[0][row1]*matrix[1][row2]*matrix[2][row3]

print(matrix)            
print(totalArray)

Output

[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]
  [12 13 14 15]]

 [[16 17 18 19]
  [20 21 22 23]
  [24 25 26 27]
  [28 29 30 31]]

 [[32 33 34 35]
  [36 37 38 39]
  [40 41 42 43]
  [44 45 46 47]]]
[[[[    0.   561.  1224.  1995.]
   [    0.   629.  1368.  2223.]
   [    0.   697.  1512.  2451.]
   [    0.   765.  1656.  2679.]]

  [[    0.   693.  1496.  2415.]
   [    0.   777.  1672.  2691.]
   [    0.   861.  1848.  2967.]
   [    0.   945.  2024.  3243.]]

  [[    0.   825.  1768.  2835.]
   [    0.   925.  1976.  3159.]
   [    0.  1025.  2184.  3483.]
   [    0.  1125.  2392.  3807.]]

  [[    0.   957.  2040.  3255.]
   [    0.  1073.  2280.  3627.]
   [    0.  1189.  2520.  3999.]
   [    0.  1305.  2760.  4371.]]]


 [[[ 2048.  2805.  3672.  4655.]
   [ 2304.  3145.  4104.  5187.]
   [ 2560.  3485.  4536.  5719.]
   [ 2816.  3825.  4968.  6251.]]

  [[ 2560.  3465.  4488.  5635.]
   [ 2880.  3885.  5016.  6279.]
   [ 3200.  4305.  5544.  6923.]
   [ 3520.  4725.  6072.  7567.]]

  [[ 3072.  4125.  5304.  6615.]
   [ 3456.  4625.  5928.  7371.]
   [ 3840.  5125.  6552.  8127.]
   [ 4224.  5625.  7176.  8883.]]

  [[ 3584.  4785.  6120.  7595.]
   [ 4032.  5365.  6840.  8463.]
   [ 4480.  5945.  7560.  9331.]
   [ 4928.  6525.  8280. 10199.]]]


 [[[ 4096.  5049.  6120.  7315.]
   [ 4608.  5661.  6840.  8151.]
   [ 5120.  6273.  7560.  8987.]
   [ 5632.  6885.  8280.  9823.]]

  [[ 5120.  6237.  7480.  8855.]
   [ 5760.  6993.  8360.  9867.]
   [ 6400.  7749.  9240. 10879.]
   [ 7040.  8505. 10120. 11891.]]

  [[ 6144.  7425.  8840. 10395.]
   [ 6912.  8325.  9880. 11583.]
   [ 7680.  9225. 10920. 12771.]
   [ 8448. 10125. 11960. 13959.]]

  [[ 7168.  8613. 10200. 11935.]
   [ 8064.  9657. 11400. 13299.]
   [ 8960. 10701. 12600. 14663.]
   [ 9856. 11745. 13800. 16027.]]]


 [[[ 6144.  7293.  8568.  9975.]
   [ 6912.  8177.  9576. 11115.]
   [ 7680.  9061. 10584. 12255.]
   [ 8448.  9945. 11592. 13395.]]

  [[ 7680.  9009. 10472. 12075.]
   [ 8640. 10101. 11704. 13455.]
   [ 9600. 11193. 12936. 14835.]
   [10560. 12285. 14168. 16215.]]

  [[ 9216. 10725. 12376. 14175.]
   [10368. 12025. 13832. 15795.]
   [11520. 13325. 15288. 17415.]
   [12672. 14625. 16744. 19035.]]

  [[10752. 12441. 14280. 16275.]
   [12096. 13949. 15960. 18135.]
   [13440. 15457. 17640. 19995.]
   [14784. 16965. 19320. 21855.]]]]

The thing is that the category arrays are always equal, the triangular matrix. Maybe it would be sufficient to have one triangular array and do the multiplication with it. At the end i want to give a array of indices lists like [[0,0,0,1],[0,0,0,2]] to get the two bool values for that multiplication.

You need to spread out that second axis to create two 4D versions and let them multiply against each other -

matrix[:,None,:,:]*matrix[:,:,None,:]

Or simply -

matrix[:,None]*matrix[...,None,:]

Outer-operation

Explanation with schematic :

We are looking to perform outer-elementwise multiplication against each other along the second axis. So, we need to extend axes and create two 4D array versions such that there's singleton(axis with length=1) corresponding to a full-axis-length version in another. We are doing this dimension-extension with np.newaxis/None .

Consider a 2D case of shape (3,5) :

matrix : 3 x 5

Let's do outer-elementwise multiplication along the second axis. So, the extension of arrays would be -

matrix-version1 : 3 x 1 x 5
matrix-version2 : 3 x 5 x 1

Similarly, for performing outer-elementwise multiplication along the first axis, it would be -

matrix-version1 : 1 x 3 x 5
matrix-version2 : 3 x 1 x 5

Thus, extending this to our 3D case for outer-elementwise multiplication along the second axis and assuming a shape of (m,n,r) , it would be -

matrix-version1 : m x 1 x n x r # [:,None,:,:]
matrix-version2 : m x n x 1 x r # [:,:,None,:]

Hence, after elementwise multiplication resulting in :

output          : m x n x n x r

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM