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

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

If you run the following code, you’ll experience a special ValueError:

import numpy as np
a = np.array([1, 2, 3])
b = bool(a)
print(b)

The output will be this error message:

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

Try It Yourself in our interactive browser shell:

Solution: Using the Numpy functions called logical_and() and logical_or() instead of Python’s logical operators (“and” and “or”) is the solution.

Why does the ValueError occur at all?

Many programmers who start learning Numpy think they can use Python’s logical operators while writing code, but the creators of this module have decided that there is not one commonly understood way to rate an array in a boolean context.

It might mean True if any element is True, or True if all elements are True, or True if the array is of non-zero length. And we only mentioned three possibilities—there are more!

Because different users may have various needs and goals, developers refused to speculate and decided to raise the ValueError each time someone tries to evaluate an array in a Boolean context, so what did they give in exchange?

Logical_and() function – the equivalent for “and”

The logical_and() function is equivalent to the Python built-in “and” logical operator. When we use this function, the program will return an array with True and False values. 

This function has two crucial parameters, i.e. our input arrays, which we put after the comma (in this example arr1 < 3 and arr_2 > 3). Let’s take a look at the example:

import numpy as np

arr_1 = np.arange(5)
arr_2 = np.arange(6, 10)
arr_3 = np.array(['First', 'Second', 'Third', 'Fourth', 'Fifth'])

mask = np.logical_and(arr_1 < 3, arr_2 > 3)
print(arr_3[mask])

Output:

['First' 'Second' 'Third']

The code printed the first, second and third element of the array arr_3, because it checked our conditions and it came out that the first three numbers of our arrays meet the conditions at the same time. 

Logical_or() function – the equivalent for “or”

The functionality is the same as the previous one. It also has two most important parameters—input arrays. The only difference is in the behavior of the code, after all we want to achieve something different:

import numpy as np

arr_1 = np.arange(5)
arr_2 = np.arange(5, 10)
arr_3 = np.array(['First', 'Second', 'Third', 'Fourth', 'Fifth'])

mask = np.logical_or(arr_1 >= 3, arr_2 < 3)
print(arr_3[mask])

As at least one of the elements in positions 4 and 5 of our arrays meets our condition, the result is as follows:

['Fourth' 'Fifth']

Logical And with “&” and Logical Or with “|”

Instead of writing logical_and() or logical_or() we can use & and | symbols. Take a look at this code: 

import numpy
arr_1 = np.arange(5)
arr_2 = np.arange(5, 10)
arr_3 = np.array(['First', 'Second', 'Third', 'Fourth', 'Fifth'])

# Same functionality as logical_and
mask = np.array((arr_1 < 3) & (arr_2 > 3))
print(arr_3[mask])

# Same functionality as logical_or
mask = np.array((arr_1 >= 3) | (arr_2 < 3))
print(arr_3[mask])

Output:

['Fourth' 'Fifth']
['First' 'Second' 'Third']

any() and all()

As these two functions appear in the topic, here is a quick explanation of what they do at all!

The function any() checks if any of the elements are non-zero and all() checks if all elements are non-zero.These functions takes several parameters, but two are the most important:

  • a -> Input array or object that can be converted to an array.
  • axis -> Axis or axes along which a logical OR reduction is performed. The default (axis=None) is to perform a logical OR over all the dimensions of the input array. axis may be negative, in which case it counts from the last to the first axis.
arr_1 = np.array([[1, 2, 3, 0],[0, 1, 2, 3]])

print('Outputs of function any')
print(np.any(arr_1))
print(np.any(arr_1, axis=0))
print(np.any(arr_1, axis=1))

print('\nOutputs of function all')
print(np.all(arr_1))
print(np.all(arr_1, axis=0))
print(np.all(arr_1, axis=1))

Output:

Outputs of function any:
True
[ True  True  True  True]
[ True  True]
 
Outputs of function all:
False
[False  True  True False]
[False False]

As you can see, our script checked at the beginning if any values along the axis are not zero.

Note: axis=0 is a vertical axis and axis=1 is a horizontal axis.

Summary

We learned why there is a ValueError error when we want to use the logical operators built into Python (“and” and “or”) in logical operations while using arrays. Next, there were 2 equivalents of these logical operators (“logical_and” and “logical_or”) and an even faster way to achieve the same. Finally, the function any() and all() in the Numpy module was explained.

References