[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,
Jonathan
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