0

I am desperately trying to multiply a vector with a matrix. The problem is that the python console shows me this error:

ValueError: operands could not be broadcast together with shapes (4,20) (4,2)

I tried a solution from Stackoverflow and it did work but not for my matrix and vector.

My arrays that do not work:

a = np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]])

b = np.array([1, 5, 10, 22])
solution = a*b

My expected solution should look like this:

[[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[5, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 22, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0]]

The arrays that works:

a = np.array([[3,2], [4, 5],[1,3]])
b = np.array([2, 4, 1])
solution = a*b

I do not know what is wrong with my two arrays.

  • No I want another output – programmer73 Apr 21 '21 at 20:02
  • This is actually a math problem. You can't do this operation because of the wrong shape. The inner dimension must be the same: (20,4) (4,2) not (4,20) (4,2). So you can easily transform the first matrix. solution = a.T*b, then it is mathematically correct. – MarkusOdenthal Apr 21 '21 at 20:04

1 Answers1

1
In [67]: a = np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...:    [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...:    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    ...:    [0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]])
    ...: 
    ...: b = np.array([1, 5, 10, 22])

Note the shape:

In [68]: a.shape
Out[68]: (4, 20)
In [69]: b.shape
Out[69]: (4,)

We can add a dimension to b. Some like to call this a column vector

In [70]: b[:,None].shape
Out[70]: (4, 1)

Now the multiplication works as you want:

In [71]: a*b[:,None]
Out[71]: 
array([[ 0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0],
       [ 5,  5,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0],
       [ 0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0],
       [ 0, 22,  0,  0,  0, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0, 22,
         0,  0,  0,  0]])

A key concept in numpy is broadcasting. It controls how arrays with different shapes are combined.

Here a (4,20) and (4,1) produce a (4,20), because the size 1 dimension is expanded to match the 20.

Without the b adjustment:

In [72]: a*b
Traceback (most recent call last):
  File "<ipython-input-72-8ce765dcfa30>", line 1, in <module>
    a*b
ValueError: operands could not be broadcast together with shapes (4,20) (4,) 

If the number of dimensions don't match, it can adjust them by adding a leading dimension, (1,4). But that 1 is in the wrong place.

In the original error (4,20) (4,2), there isn't a size 1 to adjust, and 20 does not equal 2.

In the last example you have a (2,3) and (3,). The (3,) expands to (1,3) and on to (2,3). Now the dimensions match.

The original "duplicate" was for matrix multiplication, a different operations, with different rules pairing dimensions.

hpaulj
  • 175,871
  • 13
  • 170
  • 282