Why do "Not a Number" values equal True when cast as boolean in Python/Numpy?

PythonMathNumpy

Python Problem Overview


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.)

Python Solutions


Solution 1 - Python

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

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 - Python

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 - 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).

Solution 5 - Python

This is usually needed when testing variables for np.nan. While np.nan is not np.nan fails (evaluates to False), the np.isnan function works (evaluates to True, so can be used to test for np.nan):

np.isnan(np.nan) > True

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrroowwllaannddView Question on Stackoverflow
Solution 1 - PythonNPEView Answer on Stackoverflow
Solution 2 - PythonicecrimeView Answer on Stackoverflow
Solution 3 - PythonmgilsonView Answer on Stackoverflow
Solution 4 - PythonKelseyView Answer on Stackoverflow
Solution 5 - PythonmirekphdView Answer on Stackoverflow