Use A.Any() or A.All()

Understanding the use of any() and all() in numpy arrays

any() and all() are intended for boolean arrays. any() returns True if there's any values that are equal to True in the array. all() returns True if all values in the array are equal to True.
For integers/floats the functionality is similar, except that they return True if the value 0 is not found in the array.
In your example, since both a.any() and a.all() will return True, it follows that a.any() == a.all().

Try executing the following code to see how it works in practice.

a = np.asarray([1,2,3])
b = np.asarray([-1,0,1])
c = np.asarray([True, False])

print(a.any())
print(a.all())

print(b.any())
print(b.all())

print(c.any())
print(c.all())

Why do I have to use a.any() or a.all() in this code?

when evaluating if statements, you have to pass in a bool.

if var:
pass

var has to be of type bool.

if x is a number, then x%2 == 1 is a bool.

if x is a np.array, then x%2 == 1 is a np.array which isn't a bool, but rather an array of bool, in which each cell states whether *that cell* %2 == 1.

You can check if all elements in it are truthy (1) or if any of them are truthy with np.all or np.any.

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

Python: Use a.any() or a.all() while traversing a numpy.ndarray

Normally, you can compare two numbers to get a truth value. For example:

elem = 5
if elem < 6:
# do something

is equivalent to:

if true:
# do something

However, you can't compare an array to a value. For example:

elem = [5,7]
if elem < 6:
# this doesn't make sense

Instead, you can get the truth value of whether any or all elements satisfy the condition. For example:

elem = np.array([5,7])
if np.any(elem<6):
# this is true, because 5 < 6
if np.all(elem<6):
# this isn't true, because 7 > 6

I ran your example code above and found no error, so I'm not sure what the issue is. But this is what you should look out for. Consider printing the element you are comparing to see if it is an array.


Also, this is a shorter way of doing what you want to do:

myarray = np.array( putarrayhere )
count = sum(myarray >= value)

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)

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

The truth value of an array with more than one element is ambiguous. Removing nan from list of lists

The issue is that you cannot test the NaN status on a list. You should only test is on floats.

For this you can use:

newlist = [x for x in mylist if not isinstance(x, float) or not np.isnan(x)]

alternatively:

newlist = [x for x in mylist if isinstance(x, list) or not np.isnan(x)]

Due to short-circuiting, the np.isnan(x) will only be evaluated if x is a float (or not a list in the alternative), which won't trigger an error.

output: [[1, 2], [8], [6]]

i have an error of a.any() and a.all() value error in the if statement

As the code is written, the variable N stores each item of L0 for every iteration. It looks like L0 is a list containing Q based on the code preceding the loop. This is due to the r3 = np.arange() line.

One of the first things I would do is confirm that things are working as expected. For example, adding a simple print(N) inside the loop to confirm that N truly is an array of floating values (i.e. Q):

for N in L0:
print( N )
...

Assuming all this is expected, it is not syntactically correct to compare an array to a single value, which is why the error suggested using either the .all() or .any() functions. This would have a syntax like the following if we are checking if any of the elements in N (and therefore Q) is greater than or equal to 100:

if ( N <= 100 ).any():
...

And the following if we want to check if all the elements in N is greater than or equal to 100:

if ( N <= 100 ).all():
...


Related Topics



Leave a reply



Submit