0

What I want is really simple but I can't figure out how to do it on numpy.

I have the following matrix:

M = [[1, 1, 1],
     [1, 1, 1],
     [1, 1, 1]]

And this array:

A = [1, 2, 3]

I want to multiply the matrix with each element on the array on a way to produce:

[[[1, 1, 1],
  [1, 1, 1],
  [1, 1, 1]],
 [[2, 2, 2],
  [2, 2, 2],
  [2, 2, 2]],
 [[3, 3, 3],
  [3, 3, 3],
  [3, 3, 3]]]

without any for loops, I want just a numpy function.

4
  • I’m not sure about “without any loops” as you need each element of the array; hence a loop. Something similar to np.array([M*i for i in A]) perhaps? Commented Aug 17, 2020 at 17:48
  • You have an iterative process; you must have some sort of loop, even if it's implicit. Note that this is not a typical NumPy broadcasting operation: you're not replicating A to the size of M for element-wise operations. Rather, you want your output shape to be the product of the two sizes. Commented Aug 17, 2020 at 17:53
  • What I can do is pass M with the same shape as A (copying on the third axis) and apply element-wise operations. I just can't use a python for loop. Commented Aug 17, 2020 at 18:03
  • And I take it back! There are two brilliant solutions below. Learned something new today! :-) Commented Aug 17, 2020 at 18:21

2 Answers 2

3
In [146]: M = np.ones((3,3),int)                                                                     
In [147]: M                                                                                          
Out[147]: 
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])
In [148]: A = np.array([1,2,3])   

broadcasted multiplication does this:

In [149]: A[:,None,None]*M                                                                           
Out[149]: 
array([[[1, 1, 1],
        [1, 1, 1],
        [1, 1, 1]],

       [[2, 2, 2],
        [2, 2, 2],
        [2, 2, 2]],

       [[3, 3, 3],
        [3, 3, 3],
        [3, 3, 3]]])

A is changed to (3,1,1); M is automatically broadcast to (1,3,3), together (3,3,3)

Sign up to request clarification or add additional context in comments.

1 Comment

By the way, if I change M to 4 x 4, why the same code doesn't work?
3

Using einsum

np.einsum('ij,k->kji', M, A)

array([[[1, 1, 1],
        [1, 1, 1],
        [1, 1, 1]],

       [[2, 2, 2],
        [2, 2, 2],
        [2, 2, 2]],

       [[3, 3, 3],
        [3, 3, 3],
        [3, 3, 3]]])

Comments