0

Numpy seems to have some (to me) unintuitive behaviour with broadcasting arrays. Let's say we have two arrays

a = numpy.ones((2,2,3))
b = numpy.array([[1],[2]])

I would expect to be able to multiply these together, with the output being

>>> a*b
array([[[1., 1., 1.],
        [1., 1., 1.]],

       [[2., 2., 2.],
        [2., 2., 2.]]])

However instead we get

>>> a*b
array([[[1., 1., 1.],
        [2., 2., 2.]],

       [[1., 1., 1.],
        [2., 2., 2.]]])

In fact, this multiplication only works because the second dimension of a is the same as the outer dimension of b (2, in this case). If instead we have a = numpy.ones((2,3,3)), I get the following error:

>>> a*b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2,3,3) (2,1)

The reason I find this strange is that broadcasting together arrays with shapes (3,4) and (1,) would work just fine - so why doesn't it work when they are 'sub-arrays' of two larger arrays?

And what is the most 'pythonic' way to do what I want? Specifically, this is to create a 3D ndarray where each of the 2D sub-arrays has a different value repeated throughout. Obviously I could just use a loop, but it doesn't seem elegant.

Notso
  • 115
  • 6

2 Answers2

3

You have a (2,2,3) and a (2,1). The 2nd is expanded to (1,2,1) (auto new axis at the front), and then to (2,2,3).

Try b[:,:,None] to make it (2,1,1).

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thanks! I now understand why what I was doing was wrong, and your solution does exactly what I need. Would you be willing to edit your answer to add a little more detail on how the syntax of your solution works? – Notso Sep 04 '18 at 08:56
1

How about?

a = np.ones((2,2,3))
b = np.array([[[1],
              [1]],
               [[2],
              [2]]])

print(a*b)


array([[[1., 1., 1.],
        [1., 1., 1.]],

       [[2., 2., 2.],
        [2., 2., 2.]]])
Khalil Al Hooti
  • 4,207
  • 5
  • 23
  • 40