6

Consider the following script:

import numpy as np

a = np.array([np.nan], dtype=float)
b = np.array([np.nan], dtype=float)
print a == b

a = np.array([np.nan], dtype=object)
b = np.array([np.nan], dtype=object)
print a == b

On my machine this prints out

[False]
[ True]

The first case is clear (as per IEEE-754), but what's going on in the second case? Why are the two NaNs comparing equal?

Python 2.7.3, Numpy 1.6.1 on Darwin.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    In the second case, all nan-objects are equal. – Daniel Nov 29 '14 at 21:04
  • 2
    @Daniel: Empirically, that's what seems to be happening, but: (1) what's the rationale for violating IEEE-754? (2) is this documented somewhere? – NPE Nov 29 '14 at 21:05
  • A simple possibility is just that this is what `list` does: `x = [numpy.nan]; x == x #>>> True`. – Veedrac Nov 30 '14 at 10:26

1 Answers1

8

On newer versions of numpy you get this warning:

FutureWarning: numpy equal will not check object identity in the future. The comparison did not return the same result as suggested by the identity (`is`)) and will change.

my guess is that numpy is using id test as a shortcut, for object types before falling back to __eq__ test, and since

>>> id(np.nan) == id(np.nan)
True

it returns true.

if you use float('nan') instead of np.nan the result would be different:

>>> a = np.array([np.nan], dtype=object)
>>> b = np.array([float('nan')], dtype=object)
>>> a == b
array([False], dtype=bool)
>>> id(np.nan) == id(float('nan'))
False
behzad.nouri
  • 74,723
  • 18
  • 126
  • 124
  • I like the hypothesis, thanks. I suppose it would not be unreasonable to characterise the behaviour as a bug. – NPE Nov 29 '14 at 21:07
  • 2
    Your example is faulty: `id(4.5)==id(float('4.5'))` is also `False`. – Daniel Nov 29 '14 at 21:15