È possibile impostare un numero su NaN o infinito?


203

È possibile impostare un elemento di un array su NaNin Python?

Inoltre, è possibile impostare una variabile su +/- infinito? In tal caso, esiste una funzione per verificare se un numero è infinito o no?


3
stackoverflow.com/questions/944700 spiega come verificare la presenza di NaN. Per Inf e -Inf è possibile eseguire il test con == ma ciò non funziona per NaN a causa delle regole IEEE754 per NaN.
David Heffernan,

Penso che il modo più affidabile sia quello di utilizzare funzioni adeguate come isinfe isnancome fornite da numpy. Vedi la mia risposta qui sotto.
Olivier Verdier,

Risposte:


272

Trasmetti dalla stringa usando float():

>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False

1
Questo mi insegnerà a non saltare con una battuta prima di leggere la domanda una seconda volta !! Scusa! Detto questo, non sarebbe male dirlo lo stesso perché è una trappola facile cadere, NaN! = NaN
David Heffernan,

2
nota anche: >>> float ('Inf') - float ('Inf') ===> nan
ntg

76

Sì, puoi usarlo numpyper quello.

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

21
Su python> = 2.6, puoi semplicemente usare math.isnan()emath.isinf()
Agos

8
numpyè piuttosto importante se tutto ciò che vuoi è NaNoinf
cz

1
Se tutto ciò di cui hai bisogno è NaNo Inf, uno potrebbe from numpy import nan, infesistere da quando è stata sollevata questa domanda.
Andrewgu,

37

È possibile impostare un numero su NaN o infinito?

Sì, in effetti ci sono diversi modi. Alcuni funzionano senza alcuna importazione, mentre altri richiedono import, tuttavia per questa risposta limiterò le librerie nella panoramica a standard-library e NumPy (che non è standard-library ma una libreria di terze parti molto comune).

La seguente tabella riassume i modi in cui è possibile creare un infinito non-un-numero o 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 paio di osservazioni al tavolo:

  • Il floatcostruttore in realtà non fa distinzione tra maiuscole e minuscole, quindi puoi anche usare float("NaN")o float("InFiNiTy").
  • Le costanti cmathe numpyrestituiscono semplici floatoggetti Python .
  • In numpy.NINFrealtà è l'unica costante che conosco che non richiede il -.
  • È possibile creare NaN e Infinity complessi con complexe 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           
    ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛

    Le opzioni con ¹ restituiscono una semplice float, non una complex.

c'è qualche funzione per verificare se un numero è infinito o no?

Sì, c'è - in effetti ci sono diverse funzioni per NaN, Infinity e né Nan né Inf. Tuttavia, queste funzioni predefinite non sono integrate, richiedono sempre 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     
╘══════════╧═════════════╧════════════════╧════════════════════╛

Ancora un paio di osservazioni:

  • Le funzioni cmathe numpyfunzionano anche per oggetti complessi, controlleranno se la parte reale o immaginaria è NaN o Infinity.
  • Le numpyfunzioni funzionano anche per numpyarray e tutto ciò che può essere convertito in uno (come liste, tuple, ecc.)
  • Ci sono anche funzioni che controllano esplicitamente l'infinito positivo e negativo in NumPy: numpy.isposinfe numpy.isneginf.
  • Pandas offre due funzioni aggiuntive per verificare NaN: pandas.isnae pandas.isnull(ma non solo NaN, corrisponde anche Nonee NaT)
  • Anche se non ci sono funzioni integrate, sarebbe facile crearle da soli (ho trascurato la verifica del tipo e la documentazione qui):

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

Per riassumere i risultati previsti per queste funzioni (supponendo che l'input sia un valore a virgola mobile):

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

È possibile impostare un elemento di un array su NaN in Python?

In un elenco non è un problema, puoi sempre includere NaN (o Infinity) lì:

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

Tuttavia, se si desidera includerlo in un array(ad esempio array.arrayo numpy.array), il tipo di array deve essere floato complexperché altrimenti tenterà di eseguire il downcast del tipo di array!

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

1
Nota: math.isnannon funziona con numeri complessi. Usa math.isnan(x.real) or math.isnan(x.imag)invece.
Jonathan H,

2

Quando si utilizza Python 2.4, provare

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

Sto affrontando il problema durante il porting di simplejson su un dispositivo incorporato che eseguiva Python 2.4, float("9e999")risolto il problema. Non usare inf = 9e999, è necessario convertirlo da stringa. -infdà il -Infinity.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.