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

11,540

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

Share:
11,540

Related videos on Youtube

rroowwllaanndd
Author by

rroowwllaanndd

Updated on September 15, 2022

Comments

  • rroowwllaanndd
    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
      Fred Foo over 10 years
      My 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
      jerry over 10 years
      This 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 that NaNs do not compare equal to 0 and thus convert to 1.
  • Fred Foo
    Fred Foo over 10 years
    It's not up to the language designers; the Numpy folks could have decided to make nan false as well.
  • mgilson
    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 for numpy to do what python does.
  • Warren Weckesser
    Warren Weckesser over 10 years
    I think you meant "... evaluates to False if ..."
  • Kelsey
    Kelsey over 10 years
    @Warren -- indeed! Thanks.
  • Jostikas
    Jostikas about 7 years
    Should note that -0.0 is also False. It's a thing that may at first not be trivial.
  • Kardo Paska
    Kardo Paska over 3 years
    TL;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
    Michael Tuchman about 3 years
    I think it should be NaN in all types. That is, boolean should have a NaN value. NaN should never cast to a valid value.