В большинстве языков есть константа NaN, которую вы можете использовать для назначения переменной значение NaN. Может ли python делать это без использования numpy?
Назначение переменной NaN в python без numpy
Ответ 1
Да - используйте float('nan')
. С Python 3.5 вы также можете использовать math.nan
.
>>> a = float('nan')
>>> print(a)
nan
>>> print(a + 2)
nan
>>> a == a
False
>>> import math
>>> math.isnan(a)
True
>>> # Python 3.5+
>>> math.isnan(math.nan)
True
Функция float(...)
нечувствительна к регистру - выполнение float('nan')
или float('nan')
или аналогичные вещи также будут работать.
Обратите внимание, что проверка того, что две вещи, которые являются NaN равны друг другу, всегда вернет false. Частично это объясняется тем, что две вещи, которые "не являются числом", не могут (строго говоря) быть равными друг другу - см. В чем обоснование всех сравнений, возвращающих false для IEEE754 NaN значения? для получения более подробной информации и информации.
Вместо этого используйте math.isnan(...)
, если вам нужно определить, является ли значение NaN или нет.
Кроме того, точная семантика операции ==
по значению NaN может вызвать незначительные проблемы при попытке сохранить NaN внутри типов контейнеров, таких как list
или dict
(или при использовании пользовательских типов контейнеров). Подробнее см. Проверка наличия NaN в контейнере.
Вы также можете построить числа NaN, используя модуль Python decimal:
>>> 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(...)
также будет работать с десятичными объектами.
Однако вы не можете построить числа NaN в Python 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.
Кстати, вы также можете сделать 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'))
)
Ответ 2
nan = float('nan')
И теперь у вас есть константа, nan
.
Аналогичным образом вы можете создавать значения NaN для decimal.Decimal.:
dnan = Decimal('nan')
Ответ 3
Используйте float("nan")
:
>>> float("nan")
nan
Ответ 4
Вы можете сделать float('nan')
, чтобы получить 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)
Ответ 6
Вы можете получить NaN из "inf-inf", и вы можете получить "inf" с номера больше 2e308, поэтому я обычно использовал:
>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan