# [Numpy-discussion] newbie question about boolean testing of array equality result

Jonathan Hartley tartley@tartley....
Wed Mar 23 19:09:21 CDT 2011

```Thanks for the responses, folks.

Robert, thanks for helping me come to terms with the situation, for
pointing out the perils of comparing NaNs, and particularly for the "not
isinstance(x, bool)" idea - some variant of this or attribute checking
as you suggest sounds like what we'll use.

Daniel, thank you also for your thoughtful guidance on floating point
numerical accuracy, and the best way to tackle comparisons using numpy.
However, I'm reluctant to go down that route - as I say, we otherwise
don't have any dependency on Numpy, and I'm reluctant to add one merely
so that I can stop numpy arrays from raising exceptions.

The sample code I showed you was over-simplified for clarity, perhaps to
the point of actually being misleading, for which I apologise. We're
comparing the result not just to NaN (for which we're actually, on
reflection, using math.is_nan()) but also to many other values, of
various types - The example of "== float('nan')" was just a (with
hindsight, badly chosen) representative example of that.

Best regards, and thanks for putting up with my whining,

Jonathan

On 23/03/2011 14:59, Robert Kern wrote:
> On Wed, Mar 23, 2011 at 09:29, Jonathan Hartley<tartley@tartley.com>  wrote:
>> Hey people,
>>
>> I'm writing an application in which we evaluate user-supplied Python
>> expressions.
>>
>> Sometimes, we want to do an equality test on the result of the evaluation,
>> eg:
>>
>>      result = eval(...)
>>      if result == float('nan'):
>>           ...
> Please note that this particular expression will *never* work, even
> with float objects. float('nan') != float('nan'). It's a quick of
> floating point semantics.
>
>> If the result is a numpy array, then this raises a ValueError, since the
>> array equality operator returns a new numpy array, and the coercion of this
>> to a boolean for the if predicate then explicitly raises. Presumably this is
>> well-known?
> Yes.
>
>> For us, it is undesirable.
>>
>> Am I right to understand that any code which might ever encounter a numpy
>> array therefore can never use an unguarded  'if x == y:' construction? Is my
>> workaround really to replace every instance of this with 'if not
>> isinstance(x, numpy.array) and x==y:' ? This pains me, because otherwise
>> this code would have no dependency on numpy. (I can't just prepend
>> 'isinstance(x, float)' because, unlike the example above, we don't always
>> know the type of the equality RHS until runtime.)
> def equals(x, y):
>      z = x == y
>      if not isinstance(z, bool):
>          # Or maybe you check for the existence of .all() or .any()
> depending on which semantics you would like in the presence of numpy
> arrays.
>          z = False
>      return z
>
>> I can see that there's a pleasing symmetry to have all the array arithmetic
>> operators and comparisons operate in an element-wise manner, but I think
>> it's more important for __eq__ to follow it's usual semantics of returning a
>> boolean. I'd way prefer it if the element-wise equality array generation was
>> exposed as a different method.
> I'm afraid that it is far too late to make such a change.
>

--
Jonathan Hartley    tartley@tartley.com    http://tartley.com