How to use numpy.all() or numpy.any()?

CodingAmateur picture CodingAmateur · Nov 26, 2016 · Viewed 22.5k times · Source

I am trying to search in a 2D numpy array for a specific value, the get_above method returns a list of coordinates above the character 'initial char'

def get_above(current, wordsearch):
list_of_current_coords = get_coords_current(current, wordsearch)
#print(list_of_current_coords)
length = len(list_of_current_coords)
first_coords = []
second_coords = []
for x in range(length):
    second = list_of_current_coords[x][1]
    new_first = list_of_current_coords[x][0] - 1
    first_coords.append(new_first)
    second_coords.append(second)
combined = [first_coords, second_coords]
above_coords = []
for y in range(length):
    lst2 = [item[y] for item in combined]
    above_coords.append(lst2)   
return above_coords

def search_above(initial_char, target, matrix):
    above_coords = get_above(initial_char, matrix)
    length = len(above_coords)
    for x in range(length):
        if matrix[above_coords[x]] == target:
            print(above_coords[x])
        else:
            print('not found')

And I get this error when calling the function:

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

Any help would be appreciated!

Answer

hpaulj picture hpaulj · Nov 26, 2016

The ValueError is caused by an array comparison in the if statement.

Lets make a simpler test case:

In [524]: m=np.arange(5)
In [525]: if m==3:print(m)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-525-de75ce4dd8e2> in <module>()
----> 1 if m==3:print(m)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [526]: m==3
Out[526]: array([False, False, False,  True, False], dtype=bool)

The m==3 test produces a boolean array. That can't be used in an if context.

any or all can condense that array into one scalar boolean:

In [530]: (m==3).any()
Out[530]: True
In [531]: (m==3).all()
Out[531]: False

So in

if matrix[above_coords[x]] == target:
        print(above_coords[x])

look at matrix[above_coords[x]] == target, and decide exactly how that should be turned into a scalar True/False value.