minovsky
minovsky

Reputation: 857

sum product of 2d with 3d numpy arrays plus a scalar computation

just asked a basic question earlier on dot product of two 2d arrays with hopes that I can then figure out how to expand the logic to the following question where one matrix is actually in 3d and then further multiplied by a 1d scalar vector, with no success... sorry for the back-to-back questions, numpy looks much more complicated that I thought..

I have the following 3 arrays

a = np.array([[1, 2, 3], [3, 4, 5]])
b = np.array([[[1, 0, 1], [1, 1, 0], [0, 1, 1]], [[1, 1, 1], [0, 1, 0], [0, 0, 1]]])
c = np.array([1, 2, 3])

I'd like to do the following computation. I am just going to type out the formula directly as I am not sure how to properly describe it in words (if someone can enlighten me on this as well I would be interested to know!)...

[[(1*1 + 0*2 + 1*3)/1, (1*1 + 1*2 + 0*3)/2, (0*1, 1*2, 1*3)/3],
 [(1*3 + 1*4 + 1*5)/1, (0*3 + 1*4 + 0*5)/2, (0*3, 0*4, 1*5)/3]]

>>> [[4, 1.5, 1.67], [12, 2, 1.67]]

it probably have to do with how to use the axis arg but I can't figure out quite yet... thanks much again!!

Upvotes: 1

Views: 358

Answers (2)

mathfux
mathfux

Reputation: 5949

Correct answer: np.sum((a[:,None,:] * b), axis=2) / c

Process step by step visually:

enter image description here

Additional comments

  1. a[:,None,:] inserts an extra dimension in the middle of size 1. a.shape is (2, 3) and a[:,None,:] is (2, 1, 3). a[None,:,:] and [a[:,:,None] does the same, you can check it with a shape parameter.

  2. One of approaches of understanding this problem is visual. All the pictures demonstrate how three dimensions corresponds to axis=0, axis=1, axis=2. So if you had an array of shape = (2, 1, 3), its visualisation would be a cuboid of height = 2, width = 1 and lenght = 3. For example, you can see visually how a[:,:,None] and b are broadcasted into a new array a[:,:,None] * b.

  3. There's also a symbolic (formal) way to see it. Only arrays of balanced shapes could be broadcasted. So arrays of shapes (2, 3) and (2, 1, 3) can't be broadcasted unlikely to arrays of shapes (2, 3, 3) and (2, 1, 3). But, arrays of shapes (4, 3) and (3,) can be broadcasted. I mean, there are mathematical rules which defines whether arrays are broadcastable.

Upvotes: 2

tgrandje
tgrandje

Reputation: 2514

That may not be what you were looking for exactly (as it reshapes the numpy array using a list, which is not very efficient), but it seems to work :

d = np.array([[row]*3 for row in a]) #reshape np.array to 3d
print((d*b).sum(axis=2)/c)

Upvotes: 1

Related Questions