2

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?

kmario23
  • 57,311
  • 13
  • 161
  • 150
ZHU
  • 904
  • 1
  • 11
  • 25
  • Have you seen https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html ? – Jon Clements Jul 15 '18 at 11:19
  • @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 Jul 15 '18 at 11:21

4 Answers4

3

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]]
Marijn van Vliet
  • 5,239
  • 2
  • 33
  • 45
2

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]])
Luca Cappelletti
  • 2,485
  • 20
  • 35
1

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
kmario23
  • 57,311
  • 13
  • 161
  • 150
0

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].

hpaulj
  • 221,503
  • 14
  • 230
  • 353