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

Posted

技术标签:

【中文标题】在没有numpy的python中分配一个变量NaN【英文标题】:Assigning a variable NaN in python without numpy 【发布时间】:2013-10-22 20:18:23 【问题描述】:

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

【问题讨论】:

C、C++、java、C#、ocaml,它是很多语言的一部分。 NaN,在 C 中是 NAN;从 C99 开始,它是在 math.h 中定义的常量。 (我觉得将该语言的最新标准化版本称为该语言是公平的。因此“C”是 C11。)(参见***.com/questions/1923837/how-to-use-nan-and-inf-in-c);在 C++ 中,它也是 NAN,还有 nan()nanf()nanl(),尽管我不太确定它们的作用。 double.NaN 在 Java 中,Double.NaN 在 C# 中...... 【参考方案1】:

是的——使用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。这部分是因为“不是数字”的两件事不能(严格来说)说彼此相等——有关更多详细信息和信息,请参阅What is the rationale for all comparisons returning false for IEEE754 NaN values?。

如果您需要确定某个值是否为 NaN,请改用 math.isnan(...)

此外,在尝试将 NaN 存储在 listdict 等容器类型中(或使用自定义容器类型时)时,== 对 NaN 值的操作的确切语义可能会导致微妙的问题。详情请见Checking for NaN presence in a container。


您还可以使用 Python 的 decimal 模块构造 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 的 fractions 模块中构造 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 模块类似的函数和常量:

cmath.isnan(...) cmath.isinf(...) cmath.isfinite(...) (Python 3.2+) cmath.nan(Python 3.6+;相当于complex(float('nan'), 0.0)cmath.nanj(Python 3.6+;相当于complex(0.0, float('nan'))cmath.inf(Python 3.6+;相当于complex(float('inf'), 0.0)cmath.infj(Python 3.6+;相当于complex(0.0, float('inf'))

【讨论】:

请注意,使用 float('nan) 比使用 np.nan 慢 3 倍,比分配一次 nan = float('nan') 然后使用变量 'nan' 慢大约 6.5 倍以下所有作业(如 abarnert 的回答中所建议的那样)。【参考方案2】:
nan = float('nan')

现在你有了常量nan

您可以类似地为 decimal.Decimal 创建 NaN 值。:

dnan = Decimal('nan')

【讨论】:

这是对多个 nan 赋值最有效的答案:即只使用一次 float('nan'),然后对所有剩余的赋值使用分配的常量。但是,如果您只执行 nan total 的一两个任务,那么使用 numpy.nan 是最快的。 Python愚蠢的API设计,为什么不添加一个float.nan常量?【参考方案3】:

使用float("nan"):

>>> float("nan")
nan

【讨论】:

【参考方案4】:

可以从“inf - inf”得到NaN,也可以从大于2e308的数得到“inf”,所以,我一般用:

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

【讨论】:

这个答案不合理地被否决了。我在 .txt 文件中编写了许多小型解析测试,并使用 ast.literal_eval 来获得预期的输出部分。在那里调用 float('nan') 是不可能的,这个答案对我很有帮助。 @VitalikVerhovodov 需要指出的是,从 Python 3.7 开始,不再可能通过 ast.literal_eval('1e999-1e999') 获得 NaN 值。有关更改的更多详细信息,请参阅bpo-31778。在过去,ast.literal_eval 似乎能够添加和减去文字,但这只是由于支持复数文字评估的松散输入验证。根据its official documentation,ast.literal_eval 不是为评估涉及运算符的表达式而设计的。【参考方案5】:

您可以通过float('nan') 获取 NaN。

【讨论】:

【参考方案6】:

生成 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)

【讨论】:

以上是关于在没有numpy的python中分配一个变量NaN的主要内容,如果未能解决你的问题,请参考以下文章

在Python的while循环条件中分配变量?

有没有办法在 SKSpriteNode 中分配和调用变量?

如何查找变量是在堆栈还是堆中分配?

是否可以在单个变量(批处理文件)中分配多个值?如果没有,有没有办法以更有效的方式运行它?

Swift 没有从 JSON 结果中分配变量

在 T-SQL 中分配 TABLE 类型变量