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

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

Most languages have a NaN constant you can use to assign a variable the value NaN. Can python do this without using numpy?


回答 0

是的-使用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

  • cmath.isnan(...)
  • cmath.isinf(...)
  • cmath.isfinite(...) (Python 3.2及更高版本)
  • (Python 3.6及更高版本;等效于complex(float('nan'), 0.0)
  • (Python 3.6及更高版本;等效于complex(0.0, float('nan'))
  • (Python 3.6及更高版本;等效于complex(float('inf'), 0.0)
  • (Python 3.6及更高版本;等效于complex(0.0, float('inf'))

Yes — use math.nan.

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

Before Python 3.5, one could use float("nan") (case insensitive).

Note that checking to see if two things that are NaN are equal to one another will always return false. This is in part because two things that are “not a number” cannot (strictly speaking) be said to be equal to one another — see What is the rationale for all comparisons returning false for IEEE754 NaN values? for more details and information.

Instead, use math.isnan(...) if you need to determine if a value is NaN or not.

Furthermore, the exact semantics of the == operation on NaN value may cause subtle issues when trying to store NaN inside container types such as list or dict (or when using custom container types). See Checking for NaN presence in a container for more details.


You can also construct NaN numbers using Python’s decimal module:

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


However, you cannot construct NaN numbers in Python’s fractions module:

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

Incidentally, you can also do float('Inf'), Decimal('Inf'), or math.inf (3.5+) to assign infinite numbers. (And also see math.isinf(...))

However doing Fraction('Inf') or Fraction(float('inf')) isn’t permitted and will throw an exception, just like NaN.

If you want a quick and easy way to check if a number is neither NaN nor infinite, you can use math.isfinite(...) as of Python 3.2+.


If you want to do similar checks with complex numbers, the cmath module contains a similar set of functions and constants as the math module:

  • cmath.isnan(...)
  • cmath.isinf(...)
  • cmath.isfinite(...) (Python 3.2+)
  • (Python 3.6+; equivalent to complex(float('nan'), 0.0))
  • (Python 3.6+; equivalent to complex(0.0, float('nan')))
  • (Python 3.6+; equivalent to complex(float('inf'), 0.0))
  • (Python 3.6+; equivalent to complex(0.0, float('inf')))

回答 1

nan = float('nan')

现在您有了常数nan

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

dnan = Decimal('nan')
nan = float('nan')

And now you have the constant, nan.

You can similarly create NaN values for decimal.Decimal.:

dnan = Decimal('nan')

回答 2

用途float("nan")

>>> float("nan")
nan

Use float("nan"):

>>> float("nan")
nan

回答 3

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

You can do float('nan') to get NaN.


回答 4

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

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

You can get NaN from “inf – inf”, and you can get “inf” from a number greater than 2e308, so, I generally used:

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

回答 5

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

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

Note that the size of a float varies depending on the architecture, so it probably best to avoid using magic numbers like 9e999, even if that is likely to work.

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)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。