4

I am looking for an optimized way of computing a element wise multiplication of a 2d array by each slice of a 3d array (using numpy).

for example:

w = np.array([[1,5], [4,9], [12,15]]) y = np.ones((3,2,3))

I want to get a result as a 3d array with the same shape as y.

Broadcasting using the * operator is not allowed. In my case, the third dimensions is very long and a for loop is not convenient.

inarighas
  • 720
  • 5
  • 24

1 Answers1

3

Given arrays

import numpy as np

w = np.array([[1,5], [4,9], [12,15]])

print(w)

[[ 1  5]
 [ 4  9]
 [12 15]]

and

y = np.ones((3,2,3))

print(y)

[[[ 1.  1.  1.]
  [ 1.  1.  1.]]

 [[ 1.  1.  1.]
  [ 1.  1.  1.]]

 [[ 1.  1.  1.]
  [ 1.  1.  1.]]]

We can multiple the arrays directly,

z = ( y.transpose() * w.transpose() ).transpose()

print(z)

[[[  1.   1.   1.]
  [  5.   5.   5.]]

 [[  4.   4.   4.]
  [  9.   9.   9.]]

 [[ 12.  12.  12.]
  [ 15.  15.  15.]]]

We might note that this produces the same result as np.einsum('ij,ijk->ijk',w,y), perhaps with a little less effort and overhead.

DrM
  • 2,404
  • 15
  • 29
  • What you see in the answer, was copied from my screen. I just tried it again to confirm. Please try creating a fresh program file and insert just those four lines of code (or seven with the print statements) – DrM Oct 11 '18 at 14:29
  • yes it works on this example, but when i use it in my computation it raises an error (it cannot broadcast on the third dimensionn when its length is not equal to the length of the first dim/...). Anyway, thank you ! – inarighas Oct 11 '18 at 14:53
  • You're right, I fixed it, missed a transpose on the y array. It now generalizes to any number > 0 in the third dimension – DrM Oct 11 '18 at 16:09
  • 1
    A note of caution, when working with sufficiently large arrays, be careful about generating a lot of cache misses and check timing. – DrM Oct 11 '18 at 16:21
  • Is there a way to do this but with matrix multiplication instead of element-wise multiplication? – natemcintosh Mar 17 '21 at 13:24
  • The einsum notation for matrix multiplication of a 2d array on each slice of a 3d array is `np.einsum("ij,jkl->ikl", a, b)` – natemcintosh Mar 25 '21 at 19:36