0

I am solving quite trivial problem. I can solve it through iteration, but its too slow.

My problem:

import numpy as np
arr3 = np.zeros(shape=[4, 4, 3])
arr2 = np.zeros(shape=[4, 4])

#This is ok but I dont want
arr3[0,0]*arr2[0,0] # thats [0,0,0]*0
#This is not ok but I need
arr3[:,:]*arr2

Simply said, i need to multiply each element from arr3[:][:] which are in format [R,G,B]) with corresponding element in arr2 which are in float (distance) and all without iteration

Thanks

kmario23
  • 57,311
  • 13
  • 161
  • 150
Martin
  • 3,333
  • 2
  • 18
  • 39

2 Answers2

0

This operation is called Hadamard product (i.e. element-wise product of two arrays). But, for this operation both arrays have to be of the same dimension. Thus, you've to promote the 2D array to 3D and then you can use simple * or numpy.einsum() as in:

In [11]: arr3 = np.arange(4*4*3).reshape(4, 4, 3)
    ...: arr2 = np.arange(4*4).reshape(4, 4)

In [12]: np.einsum('ijk, ijk -> ijk', arr3, arr2[..., np.newaxis])
Out[12]: 
array([[[  0,   0,   0],
        [  3,   4,   5],
        [ 12,  14,  16],
        [ 27,  30,  33]],

       [[ 48,  52,  56],
        [ 75,  80,  85],
        [108, 114, 120],
        [147, 154, 161]],

       [[192, 200, 208],
        [243, 252, 261],
        [300, 310, 320],
        [363, 374, 385]],

       [[432, 444, 456],
        [507, 520, 533],
        [588, 602, 616],
        [675, 690, 705]]])
kmario23
  • 57,311
  • 13
  • 161
  • 150
0

You could just expand the dimensions of the smaller array to allow for broadcasting.

This can be done e.g by using np.newaxis:

import numpy as np
arr3 = np.zeros(shape=[4, 4, 3])
arr2 = np.zeros(shape=[4, 4])

res = arr3 * arr2[..., np.newaxis])

(This is identical to what @hpaulj suggested, None and np.newaxis do the same thing.)

This will change the shape to of the smaller array to (4,4,1) and apply it along each entry along the last axis of the larger array.

Joe
  • 6,758
  • 2
  • 26
  • 47