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

Jonathan Hartley tartley at tartley.com
Wed Mar 23 20:09:21 EDT 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,


On 23/03/2011 14:59, Robert Kern wrote:
> On Wed, Mar 23, 2011 at 09:29, Jonathan Hartley<tartley at 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 at tartley.com    http://tartley.com
Made of meat.       +44 7737 062 225       twitter/skype: tartley

More information about the NumPy-Discussion mailing list