Why do "Not a Number" values equal True when cast as boolean in Python/Numpy?
Solution 1
This is in no way NumPy-specific, but is consistent with how Python treats NaNs:
In [1]: bool(float('nan'))
Out[1]: True
The rules are spelled out in the documentation.
I think it could be reasonably argued that the truth value of NaN should be False. However, this is not how the language works right now.
Solution 2
Python truth-value testing states that the following values are considered False
:
- zero of any numeric type, for example, 0, 0L, 0.0, 0j.
Numpy probably chose to stick with this behaviour and prevent NaN from evaluating to False
in a boolean context. Note however that you can use numpy.isnan
to test for NaN.
Solution 3
0.0
is the only falsy float value because that's what the language designers decided would be most useful. Numpy simply follows along. (It would be weird to have bool(np.nan)
be False
when bool(float('nan'))
is True
).
I think it is probably because that's how things work with integers. Admittedly, integers have no NaN or inf types of values, but I suppose that special cases aren't special enough to break the rules.
Solution 4
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
).
Related videos on Youtube
rroowwllaanndd
Updated on September 15, 2022Comments
-
rroowwllaanndd about 1 year
When casting a NumPy Not-a-Number value as a boolean, it becomes True, e.g. as follows.
>>> import numpy as np >>> bool(np.nan) True
This is the exact opposite to what I would intuitively expect. Is there a sound principle underlying this behaviour?
(I suspect there might be as the same behaviour seems to occur in Octave.)
-
Fred Foo over 10 yearsMy hunch: NaN is not equal to zero, so it's true when converted to boolean. If NaN were false, then conversion of floats to booleans would take two checks, one for zero and one for NaN. (But I suspect interpreting Numpy floats as booleans is not common practice anyway...)
-
jerry over 10 yearsThis is also the case in C (on which NumPy is based). From the standard:
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.
Footnote 59 explicitly states thatNaNs do not compare equal to 0 and thus convert to 1.
-
-
Fred Foo over 10 yearsIt's not up to the language designers; the Numpy folks could have decided to make
nan
false as well. -
mgilson over 10 years@larsmans -- Fair enough. I didn't notice that
numpy
was part of the OP's question. I don't think that really changes anything though. It just makes sense fornumpy
to do what python does. -
Warren Weckesser over 10 yearsI think you meant "... evaluates to
False
if ..." -
Kelsey over 10 years@Warren -- indeed! Thanks.
-
Jostikas about 7 yearsShould note that -0.0 is also False. It's a thing that may at first not be trivial.
-
Kardo Paska over 3 yearsTL;DR for linked docs: Python treats everything as
True
unless it is one of the specifically defined false cases (e.g.,None
,False
, numeric zeroes, empty sequences, user-defined classes that return one of these, etc.). -
Michael Tuchman about 3 yearsI think it should be NaN in all types. That is, boolean should have a NaN value. NaN should never cast to a valid value.