ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
If a
and b
are Boolean NumPy arrays, the &
operation returns the elementwise-and of them:
a & b
That returns a Boolean array. To reduce this to a single Boolean value, use either
(a & b).any()
or
(a & b).all()
Note: if a
and b
are non-Boolean arrays, consider (a - b).any()
or (a - b).all()
instead.
Rationale
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).
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() - followed by a TypeError
The issue boils down to the fact that you can't directly compare two numpy
arrays using ==
alone, unlike most types. You need to define a custom function to compare two values in the dictionaries to handle the different types:
import numpy as np
def compare_element(elem1, elem2):
if type(elem1) != type(elem2):
return False
if isinstance(elem1, np.ndarray):
return (elem1 == elem2).all()
else:
return elem1 == elem2
result = []
MY_LIST = [
[['Mon'], np.array([4,2,1,3]), ['text'], ['more_text', 0.1]],
[['Mon'], np.array([4,2,1,3]), ['text'], ['more_text', 0.1]],
[['Tues'], np.array([3, 1, 2, 4]), ['text2'], ['more_text2', 0.2]]
]
for group in MY_LIST:
elem_to_append = dict(zip(['A', 'B', 'C', 'D'], group))
should_append = True
for item in result:
if all(compare_element(item[key], elem_to_append[key]) for key in item):
should_append = False
break
if should_append:
result.append(elem_to_append)
print(result)
Membership for list of arrays: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() error problem
Essentially, you can't use in
to test for numpy arrays in a Python list. It will only ever work for the first element, because of an optimisation in the way Python tests for equality.
What's happening is that the implementation for list.__contains__
(which in
defers to), is using a short-cut to find a match faster, by first checking for identity. Most people using Python know this as the is
operator. This is faster than ==
equality checks because all is
has to do is see if the pointers of both objects are the same value, it is worth checking for first. An identity test works the same for any Python object, including numpy arrays.
The implementation essentially would look like this if it was written in Python:
def __contains__(self, needle):
for elem in self:
if needle is elem or needle == elem:
return True
return False
What happens for your list of numpy arrays then is this:
for q in Q
, step 1:q = Q[0]
q in Q
is then the same asQ.__contains__(Q[0])
Q[0] is self[0]
=>True
!
for q in Q
, step 2:q = Q[1]
q in Q
is then the same asQ.__contains__(Q[1])
Q[1] is self[0]
=>False
:-(Q[1] == self[0]
=>array([False, False])
, because Numpy arrays use broadcasting to compare each element in both arrays.
The array([False, False])
result is not a boolean, but if
wants a boolean result, so it is passed to (C equivalent of) the bool()
function. bool(array([False, False]))
produces the error you see.
Or, done manually:
>>> import numpy as np
>>> Q = [np.array([0, 1]), np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]
>>> Q[0] is Q[0]
True
>>> Q[1] is Q[0]
False
>>> Q[1] == Q[0]
array([False, False])
>>> bool(Q[1] == Q[0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
You'll have to use any()
and numpy.array_equal()
to create a version of list.__contains__
that doesn't use (normal) ==
equality checks:
def list_contains_array(lst, arr):
return any(np.array_equal(arr, elem) for elem in lst)
and you can then use that to get True
for your loop:
>>> for q in Q:
... print(list_contains_array(Q, q))
...
True
True
True
True
NumPy Error: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
It looks like delta_new
and delta_0
are Numpy arrays, and Numpy doesn't know how to compare them.
As an example, imagine if you took two random Numpy arrays and tried to compare them:
>>> a = np.array([1, 3, 5])
>>> b = np.array([5, 3, 1])
>>> print(a<b)
array([True, False, False])
>>> bool(a<b)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
You have to basically "pick" how to collapse the comparisons of all of the values across all of your arrays down to a single bool.
>>> (a<b).any()
True
>>> (a<b).all()
False
NumPy ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
As it says, it is ambiguous. Your array comparison returns a boolean array. Methods any() and all() reduce values over the array (either logical_or or logical_and). Moreover, you probably don't want to check for equality. You should replace your condition with:
np.allclose(A.dot(eig_vec[:,col]), eig_val[col] * eig_vec[:,col])
ValueError The truth value of an array with more than one element is ambiguous Use a any or a all
When you go through your for loop, i is already each list in A, you can check this with the below:
for i in A:
print(i)
Which returns:
[0 1 0]
[0 1 1]
[0 2 0]
[0 2 1]...
So then calling A[i][0]
gives an array each time rather than an integer, so the comparison A[i][0] == 0
is not possible. To fix your problem, either do the below, which will change your i to get an index for every element in A:
for i in range(len(A)):
if A[i][0]==0:
C.append([0.7])
elif abs(A[i][0]-A[i][1])<=1:
C.append([1])
else:
C.append([0])
Or change all instances of A[i][x]
to i[x]
, and use the each list element of A that way, as follows:
for i in A:
if i[0]==0:
C.append([0.7])
elif abs(i[0]-i[1])<=1:
C.append([1])
else:
C.append([0])
list of numpy array elements - ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
from your error I understand that you try to remove an element from an array with remove. However, you cannot do it for an array. You need to do it like this :
def triangleCase():
global Triangle, d
OA = Triangle[-1]
OB = Triangle[-2]
OC = Triangle[-3]
AB = OB - OA
AO = - OA
AC = OC - OA
ABperp = tripleProd(AC,AB,AB)
ACperp = tripleProd(AB,AC,AC)
if dot(ABperp, AO) > 0: #RAB
Triangle.remove(OC)#Triangle=np.delete(Triangle,-3,0)
d = ABperp
return False
if dot(ACperp,AO) > 0: #RAC
Triangle.remove(OB)#Triangle=np.delete(Triangle,-2,0)
d = ACperp
return False
return True #RABC
Related Topics
How to Make a Python Script Run Like a Service or Daemon in Linux
Python Pysftp Get_R from Linux Works Fine on Linux But Not on Windows
Why Is Printing to Stdout So Slow? Can It Be Sped Up
Python Ftp Get the Most Recent File by Date
What Do I Need to Read Microsoft Access Databases Using Python
How to Activate Virtualenv in Linux
Find Size and Free Space of the Filesystem Containing a Given File
What Do I Use on Linux to Make a Python Program Executable
Cqlsh Connection Error: 'Ref() Does Not Take Keyword Arguments'
Linux Command-Line Call Not Returning What It Should from Os.System
Uninstall Python Built from Source
Set Chrome Browser Binary Through Chromedriver in Python
Fail During Installation of Pillow (Python Module) in Linux