Hal T - 2 months ago 15x
Python Question

# Numpy: array > 5 yields "The truth value of an array with more than one element is ambiguous"

I know that in numpy you can't simply do conditionals on arrays as it doesn't know how to treat them and that this error is a result of that, however in my case my code is a lot simpler. I have:

``````# H and _H are 3x3 arrays with hand-assigned values
# uv1 is 3x57600 array of coordinates, hand assigned in a loop
HH = np.dot(_H,np.linalg.inv(H))
new_uv = np.dot(HH,uv1)
du = uv1[0,:] * new_uv[2,:]
u = new_uv[0,:] - du
u_greater_5 = u > 5
``````

And the last line gives me the "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()" error. u is of shape (57600,) and I can open up the interactive prompt and the following works fine:

``````>>> a = np.array([1,2,3,4,5])
>>> a > 3
array([False, False, False,  True,  True], dtype=bool)
``````

But the code in the previous block doesn't. I've also tried

``````np.greater(u,5)
u[u>5] = 1
``````

But they give the same error as well. Any ideas?

Also, I don't know if this is related, but bizarrely, trying to access u[0] gives me a 3-vector of the same 3 values (the first value in u) whereas it should be a scalar? Considering its shape is (57600,) ?

Edit: the traceback, as per request:

``````Traceback (most recent call last):
File "ros2vid.py", line 333, in <module>
process_frames(bag)
File "ros2vid.py", line 239, in process_frames
u_greater_5 = u > 5
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
``````

Here's how I generate uv1:

``````# frame is an image loaded from a ros bag
uv1 = []
im_r = frame.shape[0]
im_c = frame.shape[1]
for i in range(1, im_r):
for j in range(im_c):
uv1.append([j, i, 1])
uv1 = np.transpose(np.array(uv1))
``````

and the values of H and _H are just numbers I hard code in by hand. Something like:

``````h11 = u0 * cosphi
h12 = -alph_u
h13 = alph_u + u0 * (-cosphi + cz * sinphi)
h21 = -alph_u * sinphi + v0 * cosphi
h22 = 0
h23 = alph_v * (sinphi + cz * cosphi) + v0 * (-cosphi + cz * sinphi)
h31 = cosphi
h32 = 0
h33 = -cosphi + cz * sinphi
H = np.array([[h11, h12, h13], [h21, h22, h23], [h31, h32, h33]])
``````

All the values up there like u0, cosphi, cz, etc. are simply scalars. I've individually checked them, and _H is assigned similarly as well. I've checked the shapes of H and _H and verified them to be 3x3.

Weirdly, I just tried u == 5 and that doesn't give me an error, u > 5 does.

Answer

I suspect that `u` is a one-dimensional array of objects, and the objects are themselves one-dimensional numpy arrays with length 3. I can reproduce the behavior you report as follows. First, create a one-dimensional array of objects (length 3), and fill it with numpy arrays:

``````In [26]: u = np.empty(3, dtype=object)

In [27]: u[:] = [np.array([1, 2, 3]), np.array([4, 5, 6]), np.array([7, 8, 9])]
``````

Check the type and attributes of `u`. First, it is a numpy array with shape (3,).

``````In [28]: type(u)
Out[28]: numpy.ndarray

In [29]: u.shape
Out[29]: (3,)
``````

The first element of `u` is an array with length 3:

``````In [30]: u[0]
Out[30]: array([1, 2, 3])
``````

The `dtype` of `u` is `dtype('O')`, which is numpy's representation for the `object` data type. (If you print `u.dtype`, it will show `object`.)

``````In [31]: u.dtype
Out[31]: dtype('O')
``````

Now try `u > 5`:

``````In [32]: u > 5
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-32-7f680a2a9455> in <module>()
----> 1 u > 5

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
``````

`u == 5` doesn't generate an error, but it does generate a warning, and returns the scalar False:

``````In [33]: u == 5
/Users/warren/miniconda3/bin/ipython:1: DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.
#!/bin/bash /Users/warren/miniconda3/bin/python.app
Out[33]: False
``````

To figure out why `u` is an object array, you can work backwards, checking the `.shape` and `.dtype` attributes of the variables that you use to create `u`.

Comments