Asignar una variable NaN en python sin numpy


La mayoría de los idiomas tienen una constante NaN que puede usar para asignar a una variable el valor NaN. ¿Puede python hacer esto sin usar numpy?

Author: zelinka, 2013-10-15

6 answers

Sí use use float('nan'). A partir de Python 3.5, también puede usar 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 función float(...) no distingue mayúsculas de minúsculas doing hacer float('NAN') o float('naN') o cosas similares también funcionará.

Tenga en cuenta que comprobar si dos cosas que son NaN son iguales entre sí siempre devolverá false. Esto se debe en parte a que dos cosas que "no son un número" no pueden (estrictamente hablando) decirse que son iguales entre sí see ver ¿Cuál es la razón de todas las comparaciones ¿devuelve false para los valores NAN de IEEE754? para más detalles e información.

En su lugar, use math.isnan(...) si necesita determinar si un valor es NaN o no.

Además, la semántica exacta de la operación == en el valor NaN puede causar problemas sutiles al tratar de almacenar NaN dentro de tipos de contenedores como list o dict (o al usar tipos de contenedores personalizados). Ver Comprobación de la presencia de NaN en un contenedor para más detalles.


Usted puede también construye números NaN usando el módulo decimal 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(...) también funcionará con objetos decimales.


Sin embargo, usted no puede construir números NaN en el módulo fracciones 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.

Por cierto, también puede hacer float('Inf'), Decimal('Inf'), o math.inf (3.5+) para asignar números infinitos. (Y también ver math.isinf(...))

Sin embargo hacer Fraction('Inf') o Fraction(float('inf')) no está permitido y lanzará un excepción, como NaN.

Si desea una forma rápida y fácil de comprobar si un número no es ni NaN ni infinito, puede utilizar math.isfinite(...) a partir de Python 3.2+.


Si desea hacer comprobaciones similares con números complejos, el módulo cmath contiene un conjunto similar de funciones y constantes como el módulo math:

 108
Author: Michael0x2a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-09 04:05:13
nan = float('nan')

Y ahora tienes la constante, nan.

De manera similar, puede crear valores NaN para decimal.Decimal.:

dnan = Decimal('nan')
 11
Author: abarnert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-15 06:05:56

Use float("nan"):

>>> float("nan")
nan
 6
Author: orlp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-15 06:05:20

Puedes hacer float('nan') para obtener NaN.

 5
Author: BrenBarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-15 06:05:34

Puedes obtener NaN de "inf-inf", y puedes obtener " inf " de un número mayor que 2e308, por lo que generalmente usé:

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan
 1
Author: Junior Polegato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-04 21:20:30

Una forma más consistente (y menos opaca) de generar inf y-inf es usar de nuevo float ():

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

Tenga en cuenta que el tamaño de un flotador varía dependiendo de la arquitectura, por lo que probablemente sea mejor evitar el uso de números mágicos como 9e999, incluso si es probable que funcione.

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
Author: user3685621,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-21 22:02:08