Przypisywanie zmiennej NaN w Pythonie bez numpy
Większość języków ma stałą NaN, której można użyć do przypisania zmiennej wartości NaN. Czy python może to zrobić bez użycia numpy?
6 answers
Tak -- użyj float('nan')
. Począwszy od Pythona 3.5, można również użyć 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
Funkcja float(...)
jest niewrażliwa na wielkość liter -- Robienie float('NAN')
lub float('naN')
lub podobnych rzeczy również będzie działać.
Zauważ, że sprawdzanie, czy dwie rzeczy, które są NaN są sobie równe, zawsze zwróci false. Dzieje się tak po części dlatego, że dwie rzeczy, które nie są liczbą, nie mogą (ściśle mówiąc) być równe sobie -- zobacz Jakie jest uzasadnienie dla wszystkich porównań zwracanie false Dla wartości NaN IEEE754? Po Więcej szczegółów i informacji.
Zamiast tego użyj math.isnan(...)
jeśli chcesz określić, czy wartość jest NaN, czy nie.
Ponadto, dokładna semantyka operacji ==
na wartości NaN może powodować subtelne problemy podczas próby przechowywania NaN wewnątrz typów kontenerów, takich jak list
lub dict
(lub podczas używania niestandardowych typów kontenerów). Zobacz sprawdzanie obecności NaN w pojemniku Po Więcej Szczegółów.
Możesz również konstruuj liczby NaN używając modułu dziesiętnego Pythona:
>>> 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(...)
będzie również działać z obiektami dziesiętnymi.
Jednak nie możnakonstruować liczb NaN w module ułamków:
>>> 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.
Nawiasem mówiąc, można również zrobić float('Inf')
, Decimal('Inf')
, lub math.inf
(3.5+) aby przypisać nieskończone liczby. (Zobacz też math.isinf(...)
)
Jednak Robienie Fraction('Inf')
lub Fraction(float('inf'))
nie jest dozwolone i rzuci wyjątek, tak jak NaN.
Jeśli chcesz szybko i łatwo sprawdzić, czy liczba nie jest ani NaN, ani nieskończona, możesz użyć math.isfinite(...)
od Pythona 3.2+.
Jeśli chcesz wykonać podobne kontrole z liczbami zespolonymi, moduł cmath
zawiera podobny zestaw funkcji i stałych jak moduł math
:
cmath.isnan(...)
cmath.isinf(...)
-
cmath.isfinite(...)
(Python 3.2+) -
cmath.nan
(Python 3.6+; odpowiednikcomplex(float('nan'), 0.0)
) -
cmath.nanj
(Python 3.6+; odpowiednikcomplex(0.0, float('nan'))
) -
cmath.inf
(Python 3.6+; odpowiednikcomplex(float('inf'), 0.0)
) -
cmath.infj
(Python 3.6+; odpowiednikcomplex(0.0, float('inf'))
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-09 04:05:13
nan = float('nan')
I teraz masz stałą, nan
.
Można podobnie tworzyć wartości NaN dla dziesiętnych.Dziesiętne.:
dnan = Decimal('nan')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 06:05:56
Użycie float("nan")
:
>>> float("nan")
nan
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 06:05:20
Możesz zrobić float('nan')
, aby dostać NaN.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 06:05:34
Możesz uzyskać NaN z "inf-inf", a " inf " z liczby większej niż 2e308, więc ogólnie używałem:
>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 21:20:30
Bardziej spójnym (i mniej nieprzezroczystym) sposobem generowania inf i-inf jest ponowne użycie float ():
>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf
Zauważ, że rozmiar float ' a różni się w zależności od architektury, więc prawdopodobnie najlepiej jest unikać używania magicznych liczb, takich jak 9e999, nawet jeśli to może zadziałać.
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-21 22:02:08