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

203

¿Es posible establecer un elemento de una matriz NaNen Python?

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

Beto
fuente
3
stackoverflow.com/questions/944700 le indica cómo verificar si hay NaN. Para Inf e -Inf puede probar con == pero eso no funciona para NaN debido a las reglas IEEE754 para NaN.
David Heffernan
Creo que la forma más confiable es usar funciones adecuadas como isinfy isnansegún lo provisto por numpy. Vea mi respuesta a continuación.
Olivier Verdier

Respuestas:

272

Transmitir desde una cadena usando float():

>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False
moinudin
fuente
1
¡Eso me enseñará a no saltar con una broma antes de leer la pregunta por segunda vez! ¡Lo siento! Dicho esto, no estaría de más decirlo de todos modos porque es una trampa fácil de caer, NaN! = NaN
David Heffernan
2
también tenga en cuenta: >>> float ('Inf') - float ('Inf') ===> nan
ntg
76

Sí, puedes usar 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
fuente
21
En python> = 2.6, puede usar math.isnan()ymath.isinf()
Agos
8
numpyes una gran importación si todo lo que quieres es NaNoinf
cz
1
Si todo lo que necesita es NaNo Inf, uno podría from numpy import nan, infhaber existido desde que se planteó esta pregunta.
andrewgu
37

¿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 biblioteca estándar y NumPy (que no es biblioteca estándar sino una biblioteca de terceros muy común).

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

╒══════════╤══════════════╤════════════════════╤════════════════════╕
   result  NaN           Infinity            -Infinity          
 module                                                         
╞══════════╪══════════════╪════════════════════╪════════════════════╡
 built-in  float("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:

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

    ╒══════════╤════════════════╤═════════════════╤═════════════════════╤══════════════════════╕
       result  NaN+0j          0+NaNj           Inf+0j               0+Infj               
     module                                                                               
    ╞══════════╪════════════════╪═════════════════╪═════════════════════╪══════════════════════╡
     built-in  complex("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.

¿Hay alguna función para verificar si un número es infinito o no?

Sí, 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 un import:

╒══════════╤═════════════╤════════════════╤════════════════════╕
      for  NaN          Infinity or     not 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, verifican si la parte real o imaginaria es NaN o Infinity.
  • Las numpyfunciones también funcionan para numpymatrices y todo lo que se puede convertir en uno (como listas, tuplas, etc.)
  • También hay funciones que comprueban 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 Noney NaT)
  • Aunque no hay funciones integradas, sería fácil crearlas usted mismo (descuidé la verificación de tipo 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 es flotante):

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

¿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 un 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
fuente
1
Nota: math.isnanno funciona con números complejos. Usar en su math.isnan(x.real) or math.isnan(x.imag)lugar.
Jonathan H
2

Cuando use Python 2.4, intente

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

Estoy enfrentando el problema cuando estaba portando el simplejson a un dispositivo incrustado que ejecuta Python 2.4, lo float("9e999")solucionó. No lo use inf = 9e999, necesita convertirlo de una cadena. -infda el -Infinity.


fuente