¿Es posible establecer un número en NaN o infinito?

Resuelto zzzbbx asked hace 13 años • 5 respuestas

¿ Es posible establecer un elemento de una matriz en NaNPython?

Además, ¿es posible establecer una variable en +/- infinito? Si es así, ¿existe alguna función para comprobar si un número es infinito o no?

zzzbbx avatar Mar 26 '11 05:03 zzzbbx
Aceptado

Lanzar desde una cuerda usando float():

>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False
moinudin avatar Mar 25 '2011 22:03 moinudin

Sí, puedes usarlo numpypara eso.

import numpy as np
a = arange(3,dtype=float)

a[0] = np.nan
a[1] = np.inf
a[2] = -np.inf

a # is now [nan,inf,-inf]

np.isnan(a[0]) # True
np.isinf(a[1]) # True
np.isinf(a[2]) # True
Olivier Verdier avatar Mar 26 '2011 00:03 Olivier Verdier

¿Es posible establecer un número en NaN o infinito?

Sí, de hecho hay varias formas. Algunos funcionan sin ninguna importación, mientras que otros requieren import; sin embargo, para esta respuesta limitaré las bibliotecas en la descripción general a la biblioteca estándar y NumPy (que no es una biblioteca estándar sino una biblioteca de terceros muy común).

La siguiente tabla resume las formas en que se pueden crear un no número o un infinito positivo o negativo float:

╒══════════╤══════════════╤════════════════════╤════════════════════╕
│   result │ NaN          │ Infinity           │ -Infinity          │
│ module   │              │                    │                    │
╞══════════╪══════════════╪════════════════════╪════════════════════╡
│ built-infloat("nan") │ float("inf")       │ -float("inf")      │
│          │              │ float("infinity")  │ -float("infinity") │
│          │              │ float("+inf")      │ float("-inf")      │
│          │              │ float("+infinity") │ float("-infinity") │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ math     │ math.nan     │ math.inf           │ -math.inf          │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ cmath    │ cmath.nan    │ cmath.inf          │ -cmath.inf         │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ numpy    │ numpy.nan    │ numpy.PINF         │ numpy.NINF         │
│          │ numpy.NaN    │ numpy.inf          │ -numpy.inf         │
│          │ numpy.NAN    │ numpy.infty        │ -numpy.infty       │
│          │              │ numpy.Inf          │ -numpy.Inf         │
│          │              │ numpy.Infinity     │ -numpy.Infinity    │
╘══════════╧══════════════╧════════════════════╧════════════════════╛

Un par de comentarios a la mesa:

  • En realidad, el floatconstructor no distingue entre mayúsculas y minúsculas, por lo que también puedes usar float("NaN")o float("InFiNiTy").
  • Las constantes cmathy numpydevuelven floatobjetos Python simples.
  • En realidad , es numpy.NINFla única constante que conozco que no requiere el archivo -.
  • Es posible crear NaN e Infinity complejos con complexy cmath:

    ╒══════════╤════════════════╤═════════════════╤═════════════════════╤══════════════════════╕
    │   result │ NaN+0j0+NaNj          │ Inf+0j0+Infj               │
    │ module   │                │                 │                     │                      │
    ╞══════════╪════════════════╪═════════════════╪═════════════════════╪══════════════════════╡
    │ built-incomplex("nan") │ complex("nanj") │ complex("inf")      │ complex("infj")      │
    │          │                │                 │ complex("infinity") │ complex("infinityj") │
    ├──────────┼────────────────┼─────────────────┼─────────────────────┼──────────────────────┤
    │ cmath    │ cmath.nan ¹    │ cmath.nanj      │ cmath.inf ¹         │ cmath.infj           │
    ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛
    

    Las opciones con ¹ devuelven un simple float, no un complex.

¿Existe alguna función para comprobar si un número es infinito o no?

Sí, lo hay; de hecho, hay varias funciones para NaN, Infinity y ni Nan ni Inf. Sin embargo, estas funciones predefinidas no están integradas, siempre requieren import:

╒══════════╤═════════════╤════════════════╤════════════════════╕
│      for │ NaN         │ Infinity ornot NaN and        │
│          │             │ -Infinity      │ not Infinity and   │
│ module   │             │                │ not -Infinity      │
╞══════════╪═════════════╪════════════════╪════════════════════╡
│ math     │ math.isnan  │ math.isinf     │ math.isfinite      │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ cmath    │ cmath.isnan │ cmath.isinf    │ cmath.isfinite     │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ numpy    │ numpy.isnan │ numpy.isinf    │ numpy.isfinite     │
╘══════════╧═════════════╧════════════════╧════════════════════╛

De nuevo un par de comentarios:

  • Las funciones cmathy numpytambién funcionan para objetos complejos, comprobarán si la parte real o imaginaria es NaN o Infinity.
  • Las numpyfunciones también funcionan para numpymatrices y todo lo que se pueda convertir en uno (como listas, tuplas, etc.)
  • También hay funciones que verifican explícitamente el infinito positivo y negativo en NumPy: numpy.isposinfy numpy.isneginf.
  • Pandas ofrece dos funciones adicionales para verificar NaN: pandas.isnay pandas.isnull(pero no solo NaN, también coincide con Noney NaT)
  • Aunque no hay funciones integradas, sería fácil crearlas usted mismo (descuidé la verificación de tipos y la documentación aquí):

    def isnan(value):
        return value != value  # NaN is not equal to anything, not even itself
    
    infinity = float("infinity")
    
    def isinf(value):
        return abs(value) == infinity 
    
    def isfinite(value):
        return not (isnan(value) or isinf(value))
    

Para resumir los resultados esperados para estas funciones (suponiendo que la entrada sea un flotante):

╒════════════════╤═══════╤════════════╤═════════════╤══════════════════╕
│          input │ NaN   │ Infinity   │ -Infinity   │ something else   │
│ function       │       │            │             │                  │
╞════════════════╪═══════╪════════════╪═════════════╪══════════════════╡
│ isnan          │ TrueFalseFalseFalse            │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isinf          │ FalseTrueTrueFalse            │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isfinite       │ FalseFalseFalseTrue             │
╘════════════════╧═══════╧════════════╧═════════════╧══════════════════╛

¿Es posible establecer un elemento de una matriz en NaN en Python?

En una lista no hay problema, siempre puedes incluir NaN (o Infinity) allí:

>>> [math.nan, math.inf, -math.inf, 1]  # python list
[nan, inf, -inf, 1]

Sin embargo, si desea incluirlo en array(por ejemplo array.arrayo numpy.array), entonces el tipo de matriz debe ser floato complexporque, de lo contrario, intentará reducirlo al tipo de matriz.

>>> import numpy as np
>>> float_numpy_array = np.array([0., 0., 0.], dtype=float)
>>> float_numpy_array[0] = float("nan")
>>> float_numpy_array
array([nan,  0.,  0.])

>>> import array
>>> float_array = array.array('d', [0, 0, 0])
>>> float_array[0] = float("nan")
>>> float_array
array('d', [nan, 0.0, 0.0])

>>> integer_numpy_array = np.array([0, 0, 0], dtype=int)
>>> integer_numpy_array[0] = float("nan")
ValueError: cannot convert float NaN to integer
MSeifert avatar Feb 01 '2017 01:02 MSeifert

Cuando utilice Python 2.4, intente

inf = float("9e999")
nan = inf - inf

Me enfrenté al problema cuando estaba portando simplejson a un dispositivo integrado que ejecutaba Python 2.4 y float("9e999")lo solucionó. No lo use inf = 9e999, necesita convertirlo de cadena. -infda el -Infinity.

 avatar Feb 01 '2017 00:02