﻿ Valueerror: the Truth Value of an Array With More Than One Element Is Ambiguous. Use A.Any() or A.All() - ITCodar

# 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 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 as Q.__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 as Q.__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