Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why in numpy `nan == nan` is False while nan in [nan] is True?

Tags:

python

nan

numpy

While the first part of the question (which is in the title) has been answered a few times before (i.e., Why is NaN not equal to NaN?), I don't see why the second piece works the way it does (inspired by this question How to Check list containing NaN)?

Namely:

>> nan == nan False  >> nan in [nan] True 

An explanatory addendum to the question considering the answer from @DSM. So, why float("nan") is behaving differently from nan? Shouldn't it evaluate again to simple nan and why interpreter behaves this way?

>> x = float("nan") >> y = nan >> x nan >> y nan >> x is nan, x is float("nan"), y is nan (False, False, True) 

Basically, it refers to same generic nan in the first case, but creates separate object in the second:

>> nans = [nan for i in range(2)] >> map(id, nans) [190459300, 190459300] >> nans = [float("nan") for i in range(2)] >> map(id, nans) [190459300, 190459301] 
like image 918
sashkello Avatar asked Dec 02 '13 02:12

sashkello


People also ask

Why is NaN == NaN false?

Although either side of NaN===NaN contains the same value and their type is Number but they are not same. According to ECMA-262, either side of == or === contains NaN then it will result false value.

Is NumPy NaN false?

True where x is NaN, false otherwise. This is a scalar if x is a scalar. NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic (IEEE 754). This means that Not a Number is not equivalent to infinity.

Is NaN true or false in Python?

Numpy follows the python standard for truth testing here, any numeric type evaluates to False if and only if its numerical value is zero. Note that truth testing with NaN values can be unintuitive in other ways as well (e.g., nan == nan evaluates to False ).

Is NaN equal to NaN?

NaN is not equal to NaN! Short Story: According to IEEE 754 specifications any operation performed on NaN values should yield a false value or should raise an error.


1 Answers

nan not being equal to nan is part of the definition of nan, so that part's easy.

As for nan in [nan] being True, that's because identity is tested before equality for containment in lists. You're comparing the same two objects.

If you tried the same thing with two different nans, you'd get False:

>>> nans = [float("nan") for i in range(2)] >>> map(id, nans) [190459300, 190459284] >>> nans [nan, nan] >>> nans[0] is nans[1] False >>> nans[0] in nans True >>> nans[0] in nans[1:] False 

Your addendum doesn't really have much to do with nan, that's simply how Python works. Once you understand that float("nan") is under no obligation to return some nan singleton, and that y = x doesn't make a copy of x but instead binds the name y to the object named by x, there's nothing left to get.

like image 111
DSM Avatar answered Sep 22 '22 12:09

DSM