0
votes

When I use numpy.multiply(a,b) to multiply numpy arrays with shapes (2, 1),(2,) I get a 2 by 2 matrix. But what I want is element-wise multiplication.

I'm not familiar with numpy's rules. Can anyone explain what's happening here?

4
@JonClements I read through it but couldn't understand it very well (the are all something like 1*2*3 but in my case I've got 2*0). Can you give some explanation? - ZHU

4 Answers

2
votes

When doing an element-wise operation between two arrays, which are not of the same dimensionality, NumPy will perform broadcasting. In your case Numpy will broadcast b along the rows of a:

import numpy as np
a = np.array([[1],
              [2]])
b = [3, 4]
print(a * b)

Gives:

[[3 4]
 [6 8]]

To prevent this, you need to make a and b of the same dimensionality. You can add dimensions to an array by using np.newaxis or None in your indexing, like this:

print(a * b[:, np.newaxis]) 

Gives:

[[3]
 [8]]
1
votes

Here are the input arrays a and b of the same shape as you mentioned:

In [136]: a
Out[136]: 
array([[0],
       [1]])

In [137]: b
Out[137]: array([0, 1])

Now, when we do multiplication using either * or numpy.multiply(a, b), we get:

In [138]: a * b
Out[138]: 
array([[0, 0],
       [0, 1]])

The result is a (2,2) array because numpy uses broadcasting.

       # b
    #a | 0     1
     ------------
     0 | 0*0   0*1
     1 | 1*0   1*1
0
votes

Let's say you have two arrays, a and b, with shape (2,3) and (2,) respectively:

a = np.random.randint(10, size=(2,3))
b = np.random.randint(10, size=(2,))

The two arrays, for example, contain:

a = np.array([[8, 0, 3],
              [2, 6, 7]])
b = np.array([7, 5])

Now for handling a product element to element a*b you have to specify what numpy has to do when reaching for the absent axis=1 of array b. You can do so by adding None:

result = a*b[:,None]

With result being:

array([[56,  0, 21],
       [10, 30, 35]])
0
votes

I just explained the broadcasting rules in broadcasting arrays in numpy

In your case

(2,1) + (2,) => (2,1) + (1,2) => (2,2)

It has to add a dimension to the 2nd argument, and can only add it at the beginning (to avoid ambiguity).

So you want a (2,1) result, you have to expand the 2nd argument yourself, with reshape or [:, np.newaxis].