0

I have the following problem with shape of ndarray:

out.shape = (20,)
reference.shape = (20,0)
norm = [out[i] / np.sum(out[i]) for i in range(len(out))]
# norm is a list now so I convert it to ndarray:
norm_array = np.array((norm))
norm_array.shape = (20,30)

# error: operands could not be broadcast together with shapes (20,30) (20,) 
diff = np.fabs(norm_array - reference)

How can I change shape of norm_array from (20,30) into (20,) or reference to (20,30), so I can substract them?

EDIT: Can someone explain me, why they have different shape, if I can access both single elements with norm_array[0][0] and reference[0][0] ?

2 Answers 2

2

I am not sure what you are trying to do exactly, but here is some information on numpy arrays.

A 1-d numpy array is a row vector with a shape that is a single-valued tuple:

>>> np.array([1,2,3]).shape
(3,) 

You can create multidimensional arrays by passing in nested lists. Each sub-list is a 1-d row vector of length 1, and there are 3 of them.

>>> np.array([[1],[2],[3]]).shape
(3,1)

Here is the weird part. You can create the same array, but leave the lists empty. You end up with 3 row vectors of length 0.

>>> np.array([[],[],[]]).shape
(3,0)

This is what you have for you reference array, an array with structure but no values. This brings me back to my original point:

You can't subtract an empty array.

Sign up to request clarification or add additional context in comments.

2 Comments

Adding on that: you should read about broadcasting rules. If the last dimension of 2 arrays are different, one of them has to be 1 to be able to broadcast. In your case your last dimensions are 0 and 30, so no broadcast possible, hence the error message. You probably want reference.shape = (20,1)...
not to mention that list comprehension just outputs 1 (and nans).
0

If I make 2 arrays with the shapes you describe, I get an error

In [1856]: norm_array=np.ones((20,30))
In [1857]: reference=np.ones((20,0))
In [1858]: norm_array-reference
...
ValueError: operands could not be broadcast together with shapes (20,30) (20,0) 

But it's different from yours. But if I change the shape of reference, the error messages match.

In [1859]: reference=np.ones((20,))
In [1860]: norm_array-reference
 ...
ValueError: operands could not be broadcast together with shapes (20,30) (20,) 

So your (20,0) is wrong. I don't know if you mistyped something or not.

But if I make reference 2d with 1 in the last dimension, broadcasting works, producing a difference that matches (20,30) in shape:

In [1861]: reference=np.ones((20,1))
In [1862]: norm_array-reference

If reference = np.zeros((20,)), then I could use reference[:,None] to add that singleton last dimension.

If reference is (20,), you can't do reference[0][0]. reference[0][0] only works with 2d arrays with at least 1 in the last dim. reference[0,0] is the preferred way of indexing a single element of a 2d array.

So far this is normal array dimensions and broadcasting; something you'll learn with use.

===============

I'm puzzled about the shape of out. If it is (20,), how does norm_array end up as (20,30). out must consist of 20 arrays or lists, each of which has 30 elements.

If out was 2d array, we could normalize without iteration

In [1869]: out=np.arange(12).reshape(3,4)

with the list comprehension:

In [1872]: [out[i]/np.sum(out[i]) for i in range(out.shape[0])]
Out[1872]: 
[array([ 0.        ,  0.16666667,  0.33333333,  0.5       ]),
 array([ 0.18181818,  0.22727273,  0.27272727,  0.31818182]),
 array([ 0.21052632,  0.23684211,  0.26315789,  0.28947368])]
In [1873]: np.array(_)   # and to array
Out[1873]: 
array([[ 0.        ,  0.16666667,  0.33333333,  0.5       ],
       [ 0.18181818,  0.22727273,  0.27272727,  0.31818182],
       [ 0.21052632,  0.23684211,  0.26315789,  0.28947368]])

Instead take row sums, and tell it to keep it 2d for ease of further use

In [1876]: out.sum(axis=1,keepdims=True)
Out[1876]: 
array([[ 6],
       [22],
       [38]])

now divide

In [1877]: out/out.sum(axis=1,keepdims=True)
Out[1877]: 
array([[ 0.        ,  0.16666667,  0.33333333,  0.5       ],
       [ 0.18181818,  0.22727273,  0.27272727,  0.31818182],
       [ 0.21052632,  0.23684211,  0.26315789,  0.28947368]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.