Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy element-wise multiplication of an array and a vector

I want to do something like this:

a =  # multi-dimensional numpy array
ares = # multi-dim array, same shape as a
a.shape
>>> (45, 72, 37, 24)  # the relevant point is that all dimension are different
v = # 1D numpy array, i.e. a vector
v.shape
>>> (37)  # note that v has the same length as the 3rd dimension of a
for i in range(37):
    ares[:,:,i,:] = a[:,:,i,:]*v[i]

I'm thinking there has to be a more compact way to do this with numpy, but I haven't figured it out. I guess I could replicate v and then calculate a*v, but I am guessing there is something better than that too. So I need to do element wise multiplication "over a given axis", so to speak. Anyone know how I can do this? Thanks. (BTW, I did find a close duplicate question, but because of the nature of the OP's particular problem there, the discussion was very short and got tracked into other issues.)

like image 929
bob.sacamento Avatar asked Oct 15 '13 18:10

bob.sacamento


People also ask

Does NumPy do element-wise multiplication?

multiply() in Python. numpy. multiply() function is used when we want to compute the multiplication of two array. It returns the product of arr1 and arr2, element-wise.

How element by element multiplication is is performed on NumPy arrays?

The NumPy library's np. multiply(x1, x2) method receives two matrices as input and executes element-wise multiplication over them before returning the resultant matrix. We must send the two matrices as input to the np. multiply() method to execute element-wise input.

What is element-wise in NumPy?

isin is an element-wise function version of the python keyword in. isin(a, b) is roughly equivalent to np. array([item in b for item in a]) if a and b are 1-D sequences.


2 Answers

I tend to do something like

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

where I think I'm officially supposed to write np.newaxis instead of None.

For example:

>>> import numpy as np
>>> a0 = np.random.random((45,72,37,24))
>>> a = a0.copy()
>>> v = np.random.random(37)
>>> for i in range(len(v)):
...     a[:,:,i,:] *= v[i]
...     
>>> b = a0 * v[None,None,:,None]
>>> 
>>> np.allclose(a,b)
True
like image 160
DSM Avatar answered Nov 15 '22 14:11

DSM


Here is one more:

b = a * v.reshape(-1, 1)

IMHO, this is more readable than transpose, einsum and maybe even v[:, None], but pick the one that suits your style.

like image 21
Bi Rico Avatar answered Nov 15 '22 15:11

Bi Rico