22

I have a numpy one dimensional array c that is supposed to be filled with the contents of a + b. I'm first executing a + b on a device using PyOpenCL.

I want to quickly determine the correctness of the result array c in python using numpy slicing.

This is what I currently have

def python_kernel(a, b, c):
    temp = a + b
    if temp[:] != c[:]:
        print "Error"
    else:
        print "Success!"

But I get the error:

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

But it seems a.any or a.all will just determine whether the values aren't 0.

What should I do if I want to test if all of the scalers in the numpy array temp are equal to every value in the numpy array c?

TMWP
  • 1,545
  • 1
  • 17
  • 31
Robert
  • 673
  • 2
  • 7
  • 8
  • 4
    `all_values_are_same = all(your_array[0] == your_array):` What that does is return a list of boolean if each value equals the first value, and asserts all of them are true. – Eric Leschinski Oct 03 '16 at 18:53

3 Answers3

54

Why not just use numpy.array_equal(a1, a2)[docs] from NumPy's functions?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Amber
  • 507,862
  • 82
  • 626
  • 550
15

np.allclose is a good choice if np.array data type is floats. np.array_equal does not always work properly. For example:

import numpy as np
def get_weights_array(n_recs):
    step = - 0.5 / n_recs
    stop = 0.5
    return np.arange(1, stop, step)

a = get_weights_array(5)
b = np.array([1.0, 0.9, 0.8, 0.7, 0.6])

Result:

>>> a
array([ 1. ,  0.9,  0.8,  0.7,  0.6])
>>> b
array([ 1. ,  0.9,  0.8,  0.7,  0.6])
>>> np.array_equal(a, b)
False
>>> np.allclose(a, b)
True

>>> import sys
>>> sys.version
'2.7.3 (default, Apr 10 2013, 05:13:16) \n[GCC 4.7.2]'
>>> np.version.version
'1.6.2'
Akavall
  • 82,592
  • 51
  • 207
  • 251
  • 1
    This was giving me a headache, good to know that `np.array_equal` bombs with floats. Thanks you! – Gabriel Jan 20 '16 at 15:57
  • 1
    Usual floating point precision errors. I wouldn't blame `array_equal` for working incorrectly here. It does what it is supposed to do. Any yes, `allclose` is the correct choice for what you intend to do. – Michael May 22 '16 at 10:57
7

You would call any on the result of the comparison: if np.any(a+b != c): or equivalently if np.all(a+b == c):. a+b != c creates an array of dtype=bool, and then any looks at that array to see if any member is True.

>>> import numpy as np
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,2])
>>> c = a+b
>>> c
array([5, 7, 5]) # <---- numeric, so any/all not useful
>>> a+b == c
array([ True,  True,  True], dtype=bool) # <---- BOOLEAN result, not numeric
>>> all(a+b == c)
True

Having said all that, though, Amber's solution is probably faster since it doesn't have to create the whole boolean result array.

Community
  • 1
  • 1
mtrw
  • 34,200
  • 7
  • 63
  • 71