2

I have the following numpy code. I have one array (a) with 3d points and another with weights (b). I need to multiply each row in a by each weight in b in the corresponding row. I am hoping to make this code more understandable and eliminate the loops.

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[7, 8, 9, 10], [11, 12, 13, 14]])
c = np.zeros((2, 4, 3))

for i, row in enumerate(b):
    for j, col in enumerate(row):
        print('Mult:', a[i, :], '*', col)
        c[i, j, :] = a[i, :] * col

print(c[0, :, :])
print(c[1, :, :])

Here's the output.

Mult: [1 2 3] * 7
Mult: [1 2 3] * 8
Mult: [1 2 3] * 9
Mult: [1 2 3] * 10
Mult: [4 5 6] * 11
Mult: [4 5 6] * 12
Mult: [4 5 6] * 13
Mult: [4 5 6] * 14
[[ 7. 14. 21.]
 [ 8. 16. 24.]
 [ 9. 18. 27.]
 [10. 20. 30.]]
[[44. 55. 66.]
 [48. 60. 72.]
 [52. 65. 78.]
 [56. 70. 84.]]
0

1 Answer 1

4

You can shape the matrices differently, and then perform an element-wise multiplication:

a[:,None,:] * b[:,:,None]

So if a is an m×n-matrix and b is an m×p-matrix, we obtain an m×p×n-tensor. For the given sample data, we get:

>>> a[:,None,:] * b[:,:,None]
array([[[ 7, 14, 21],
        [ 8, 16, 24],
        [ 9, 18, 27],
        [10, 20, 30]],

       [[44, 55, 66],
        [48, 60, 72],
        [52, 65, 78],
        [56, 70, 84]]])
Sign up to request clarification or add additional context in comments.

5 Comments

Perfect. I'll accept as soon as I can. Thanks, I didn't know about that syntax.
@DanGrahnJust FYI: you should not accept answers "as soon as you can". There is a time limit specifically because people tend to accept too early. If you wait some hours/1 or 2 days other answerers have a chance to provide better, more accurate solutions. Accepting the first thing that you think solves the problem is generally a bad idea. Nothing happens if you wait tomorrow to accept this answer except possibly getting an even better answer. (Not saying that in this specific instance Willem probably has the best solution, I want to make a general statement)
@DanGrahn. Look into broadcasting. None inserts a unit dimension wherever it appears in the index. Broadcasting lets you perform an element-wise operation between a dimension with one element and multiple elements.
@Giacomo. This answer is perfect.
@GiacomoAlzetta I agree with MadPhysicist. It's exactly what I asked for and it's clear. I just couldn't figure out the NP syntax.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.