在 python 中指定一个不带 numpy 的变量 NaN

大多数语言都有一个 NaN 常量,可以用来为变量赋值 NaN。Python 可以不使用 numpy 做到这一点吗?

184510 次浏览

使用 float("nan"):

>>> float("nan")
nan

是的——使用 math.nan

>>> from math import nan
>>> print(nan)
nan
>>> print(nan + 2)
nan
>>> nan == nan
False
>>> import math
>>> math.isnan(nan)
True

在 Python 3.5之前,可以使用 float("nan")(不区分大小写)。

注意,检查两个 NaN 是否相等总是返回 false。这在一定程度上是因为“非数字”的两个事物(严格来说)不能说是相等的——参见 对于 IEEE754 NaN 值返回 false 的所有比较的基本原理是什么?了解更多细节和信息。

相反,如果需要确定一个值是否为 NaN,则使用 math.isnan(...)

此外,在尝试将 NaN 存储在容器类型(如 listdict)中(或者在使用自定义容器类型时)时,NaN 值上的 ==操作的确切语义可能会引起微妙的问题。有关详细信息,请参阅 检查容器中是否存在 NaN


您还可以使用 Python 的 十进制模块构造 NaN 数字:

>>> from decimal import Decimal
>>> b = Decimal('nan')
>>> print(b)
NaN
>>> print(repr(b))
Decimal('NaN')
>>>
>>> Decimal(float('nan'))
Decimal('NaN')
>>>
>>> import math
>>> math.isnan(b)
True

math.isnan(...) will also work with Decimal objects.


但是,您可以在 Python 的 分数模块中构造 NaN 数字:

>>> from fractions import Fraction
>>> Fraction('nan')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python35\lib\fractions.py", line 146, in __new__
numerator)
ValueError: Invalid literal for Fraction: 'nan'
>>>
>>> Fraction(float('nan'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python35\lib\fractions.py", line 130, in __new__
value = Fraction.from_float(numerator)
File "C:\Python35\lib\fractions.py", line 214, in from_float
raise ValueError("Cannot convert %r to %s." % (f, cls.__name__))
ValueError: Cannot convert nan to Fraction.

顺便说一下,你也可以做 float('Inf')Decimal('Inf'),或者 math.inf(3.5 +)来分配无限的数字

但是不允许执行 Fraction('Inf')Fraction(float('inf')),并且会抛出异常,就像 NaN 一样。

如果您想要一种快速而简单的方法来检查一个数字是否既不是 NaN 也不是无限的,那么可以使用 Python 3.2 + 中的 math.isfinite(...)


如果您想对复数进行类似的检查,cmath模块包含与 math模块类似的函数和常量集:

你可以做 float('nan')得到 NaN。

nan = float('nan')

And now you have the constant, nan.

您也可以类似地为小数创建 NaN 值:

dnan = Decimal('nan')

您可以从“ inf-inf”中获得 NaN,也可以从大于2e308的数字中获得“ inf”,因此,我通常使用:

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan

A more consistent (and less opaque) way to generate inf and -inf is to again use float():

>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf

请注意,浮点数的大小取决于体系结构,因此最好避免使用像9e999这样的神奇数字,即使这样做可能有效。

import sys
sys.float_info
sys.float_info(max=1.7976931348623157e+308,
max_exp=1024, max_10_exp=308,
min=2.2250738585072014e-308, min_exp=-1021,
min_10_exp=-307, dig=15, mant_dig=53,
epsilon=2.220446049250313e-16, radix=2, rounds=1)