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

Posted on

Solving problem is about exposing yourself to as many situations as possible like ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(), which can be followed any time. Take easy to follow this discuss.

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

I just discovered a logical bug in my code which was causing all sorts of problems. I was inadvertently doing a bitwise AND instead of a logical AND.

I changed the code from:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

TO:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]

To my surprise, I got the rather cryptic error message:

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

Why was a similar error not emitted when I use a bitwise operation – and how do I fix this?

Answer #1:

r is a numpy (rec)array. So r["dt"] >= startdate is also a (boolean)
array. For numpy arrays the & operation returns the elementwise-and of the two
boolean arrays.

The NumPy developers felt there was no one commonly understood way to evaluate
an array in boolean context: it could mean True if any element is
True, or it could mean True if all elements are True, or True if the array has non-zero length, just to name three possibilities.

Since different users might have different needs and different assumptions, the
NumPy developers refused to guess and instead decided to raise a ValueError
whenever one tries to evaluate an array in boolean context. Applying and to
two numpy arrays causes the two arrays to be evaluated in boolean context (by
calling __bool__ in Python3 or __nonzero__ in Python2).

Your original code

mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

looks correct. However, if you do want and, then instead of a and b use (a-b).any() or (a-b).all().

Answered By: unutbu

Answer #2:

I had the same problem (i.e. indexing with multi-conditions, here it’s finding data in a certain date range). The (a-b).any() or (a-b).all() seem not working, at least for me.

Alternatively I found another solution which works perfectly for my desired functionality (The truth value of an array with more than one element is ambigous when trying to index an array).

Instead of using suggested code above, simply using a numpy.logical_and(a,b) would work. Here you may want to rewrite the code as

selected  = r[numpy.logical_and(r["dt"] >= startdate, r["dt"] <= enddate)]
Answered By: Yeqing Zhang

Answer #3:

The reason for the exception is that and implicitly calls bool. First on the left operand and (if the left operand is True) then on the right operand. So x and y is equivalent to bool(x) and bool(y).

However the bool on a numpy.ndarray (if it contains more than one element) will throw the exception you have seen:

>>> import numpy as np
>>> arr = np.array([1, 2, 3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

The bool() call is implicit in and, but also in if, while, or, so any of the following examples will also fail:

>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> while arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr or arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

There are more functions and statements in Python that hide bool calls, for example 2 < x < 10 is just another way of writing 2 < x and x < 10. And the and will call bool: bool(2 < x) and bool(x < 10).

The element-wise equivalent for and would be the np.logical_and function, similarly you could use np.logical_or as equivalent for or.

For boolean arrays – and comparisons like <, <=, ==, !=, >= and > on NumPy arrays return boolean NumPy arrays – you can also use the element-wise bitwise functions (and operators): np.bitwise_and (& operator)

>>> np.logical_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)
>>> np.bitwise_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)
>>> (arr > 1) & (arr < 3)
array([False,  True, False], dtype=bool)

and bitwise_or (| operator):

>>> np.logical_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)
>>> np.bitwise_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)
>>> (arr <= 1) | (arr >= 3)
array([ True, False,  True], dtype=bool)

A complete list of logical and binary functions can be found in the NumPy documentation:

Answered By: MSeifert

Answer #4:

if you work with pandas what solved the issue for me was that i was trying to do calculations when I had NA values, the solution was to run:

df = df.dropna()

And after that the calculation that failed.

Answered By: Tomer Ben David

Answer #5:

This typed error-message also shows while an if-statement comparison is done where there is an array and for example a bool or int. See for example:

... code snippet ...
if dataset == bool:
    ....
... code snippet ...

This clause has dataset as array and bool is euhm the “open door”… True or False.

In case the function is wrapped within a try-statement you will receive with except Exception as error: the message without its error-type:

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

Answered By: ZF007

Answer #6:

Taking up @ZF007’s answer, this is not answering your question as a whole, but can be the solution for the same error. I post it here since I have not found a direct solution as an answer to this error message elsewhere on Stack Overflow.

The error appears when you check whether an array was empty or not.

  • if np.array([1,2]): print(1) –> ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

  • if np.array([1,2])[0]: print(1) –> no ValueError, but: if np.array([])[0]: print(1) –> IndexError: index 0 is out of bounds for axis 0 with size 0.

  • if np.array([1]): print(1) –> no ValueError, but again will not help at an array with many elements.

  • if np.array([]): print(1) –> DeprecationWarning: The truth value of an empty array is ambiguous. Returning False, but in future this will result in an error. Use 'array.size > 0' to check that an array is not empty.

Doing so:

  • if np.array([]).size: print(1) solved the error.
Answered By: questionto42

Answer #7:

try this=> numpy.array(r) or numpy.array(yourvariable) followed by the command to compare whatever you wish to.

Answered By: Anurag Gupta
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.