web-dev-qa-db-fra.com

Assigner une variable NaN dans python sans numpy

La plupart des langues ont une constante NaN que vous pouvez utiliser pour affecter à une variable la valeur NaN. Est-ce que python peut le faire sans utiliser numpy?

89
zelinka

Oui - utilisez float('nan'). À partir de Python 3.5, vous pouvez également utiliser 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
_

La fonction float(...) est insensible à la casse. Si vous exécutez float('NAN') ou float('naN') ou des opérations similaires, cela fonctionnera également.

Notez que vérifier si deux choses qui sont NaN sont égales retournera toujours faux. Ceci est en partie dû au fait que deux choses qui ne sont "pas un nombre" ne peuvent (à proprement parler) être considérées comme égales - voir Quelle est la raison de toutes les comparaisons renvoyant la valeur False pour les valeurs IEEE754 NaN? = pour plus de détails et d'informations.

À la place, utilisez math.isnan(...) si vous devez déterminer si une valeur est NaN ou non.

De plus, la sémantique exacte de l'opération _==_ sur la valeur NaN peut entraîner des problèmes subtils lorsque vous essayez de stocker NaN dans des types de conteneur tels que list ou dict (ou lorsque vous utilisez des types de conteneur personnalisés). Voir Vérification de la présence de NaN dans un conteneur pour plus de détails.


Vous pouvez également construire des nombres NaN en utilisant le module décimal de Python:

_>>> 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(...) fonctionnera également avec les objets décimaux.


Cependant, vous ne pouvez pas construire des nombres NaN dans le module fractions de Python:

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

Incidemment, vous pouvez également faire float('Inf'), Decimal('Inf') ou math.inf (3.5+) pour attribuer des nombres infinis. (Et aussi voir math.isinf(...) )

Cependant, faire Fraction('Inf') ou Fraction(float('inf')) n'est pas autorisé et lèvera une exception, tout comme NaN.

Si vous voulez un moyen rapide et facile de vérifier si un nombre n'est ni NaN ni infini, vous pouvez utiliser math.isfinite(...) à partir de Python 3.2+.


Si vous souhaitez effectuer des vérifications similaires avec des nombres complexes, le module cmath contient un ensemble similaire de fonctions et de constantes comme le module math:

141
Michael0x2a
nan = float('nan')

Et maintenant vous avez la constante, nan.

Vous pouvez également créer des valeurs NaN pour decimal.Decimal .:

dnan = Decimal('nan')
14
abarnert

Utilisez float("nan"):

>>> float("nan")
nan
6
orlp

Vous pouvez faire float('nan') pour obtenir NaN.

5
BrenBarn

Vous pouvez obtenir NaN à partir de "inf - inf", et "inf" à partir d'un nombre supérieur à 2e308, aussi, j'ai généralement utilisé:

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan
3
Junior Polegato

Une façon plus cohérente (et moins opaque) de générer inf et -inf consiste à utiliser de nouveau float ():

>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf

Notez que la taille d'un float varie en fonction de l'architecture. Il est donc probablement préférable d'éviter d'utiliser des nombres magiques comme 9e999, même si cela est susceptible de fonctionner.

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)
0
user3685621