在没有numpy的python中分配变量NaN


103

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


1
C,C ++,java,C#,ocaml,它是许多语言的一部分。
zelinka

2
NaN在C中是NANmath.h从C99开始,它是在中定义的常量。(我认为将这种语言的最新标准化版本称为该语言是公平的。因此,“ C”是C11。)(请参阅stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in -c); 在C ++中,它是NAN为好,还有还有nan()nanf()nanl(),虽然我为他们做什么,有点不太确定。double.NaN在Java中,Double.NaN在C#中……
Thanatos 2015年

Answers:


168

是的-使用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的基本原理是什么?了解更多详细信息。

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

此外,==在尝试将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(...) 也将与Decimal对象一起使用。


但是,您不能在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+)来分配无限数。(另请参阅math.isinf(...)

但是,这样做Fraction('Inf')Fraction(float('inf'))不允许这样做都会抛出异常,就像NaN一样。

如果您想要一种快速简便的方法来检查数字既不是NaN也不是无限,则可以使用math.isfinite(...)Python 3.2+以上版本。


如果要对复数进行类似的检查,则该cmath模块包含与该模块相似的一组函数和常量math


2
请注意,使用float('nan)的速度比使用np.nan慢3倍,比分配nan = float('nan')一次然后为所有后续分配使用变量'nan'慢大约6.5倍(如abarnert的建议)回答)。
丹尼尔·戈德法布

18
nan = float('nan')

现在您有了常数nan

您可以类似地为小数十进制创建NaN值:

dnan = Decimal('nan')

对于多个nan分配,这是最有效的答案:也就是说,仅使用float('nan')一次,然后对所有其余分配使用分配的常量。但是,如果您仅执行一或两次nan total分配,则使用numpy.nan最快。
丹尼尔·戈德法布



6

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

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

3
这个答案被不合理地拒绝了。我正在.txt文件中编写许多小型分析测试,并使用ast.literal_eval来获得预期的输出部分。在那里不能调用float('nan'),这个答案对我很有帮助。
Vitalik Verhovodov '18

0

生成inf和-inf的更一致(更不透明)的方法是再次使用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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.