Karl Alexius
Karl Alexius

Reputation: 353

Numpy: could not broadcast input array from shape (3) into shape (1)

I want to create a numpy array b where each component is a 2D matrix, which dimensions are determined by the coordinates of vector a.

What I get doing the following satisfies me:

>>> a = [3,4,1]
>>> b = [np.zeros((a[i], a[i - 1] + 1)) for i in range(1, len(a))]
>>> np.array(b)
array([ array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]]),
       array([[ 0.,  0.,  0.,  0.,  0.]])], dtype=object)

but if I have found this pathological case where it does not work:

>>> a = [2,1,1]
>>> b = [np.zeros((a[i], a[i - 1] + 1)) for i in range(1, len(a))]
>>> b
[array([[ 0.,  0.,  0.]]), array([[ 0.,  0.]])]
>>> np.array(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: could not broadcast input array from shape (3) into shape (1)

Upvotes: 0

Views: 14791

Answers (2)

busybear
busybear

Reputation: 10580

This is a bit peculiar. Typically, numpy will try to create one array from the input of np.array with a common data type. A list of arrays would be interpreted with the list as being the new dimension. For instance, np.array([np.zeros(3, 1), np.zeros(3, 1)]) would produce a 2 x 3 x 1 array. So this can only happen if the arrays in your list match in shape. Otherwise, you end up with an array of arrays (with dtype=object), which as commented, is not really an ideal scenario.

However, your error seems to occur when the first dimension matches. Numpy for some reason tries to broadcast the arrays somehow and fails. I can reproduce your error even if the arrays are of higher dimension, as long as the first dimension between arrays matches.

I know this isn't a solution, but this wouldn't fit in a comment. As noted by @roganjosh, making this kind of array really gives you no benefit. You're better off sticking to a list of arrays for readability and to avoid the cost of creating these arrays.

Upvotes: 1

Felix
Felix

Reputation: 2668

I will present a solution to the problem, but do take into account what was said in the comments. Having Numpy arrays that are not aligned prevents most of the useful operations from working their magic. Consider using lists instead.

That being said, curious error indeed. I got the thing to work by assigning in a basic for-loop instead of using the np.array call.

a = [2,1,1]
b = np.zeros(len(a)-1, dtype=object)
for i in range(1, len(a)):
    b[i-1] = np.zeros((a[i], a[i - 1] + 1))

And the result:

>>> b
array([array([[0., 0., 0.]]), array([[0., 0.]])], dtype=object)

Upvotes: 3

Related Questions