È 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
float
costruttore in realtà non fa distinzione tra maiuscole e minuscole, quindi puoi anche usare float("NaN")
o float("InFiNiTy")
.
- Le costanti
cmath
e numpy
restituiscono semplici float
oggetti Python .
- In
numpy.NINF
realtà è l'unica costante che conosco che non richiede il -
.
È possibile creare NaN e Infinity complessi con complex
e 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
cmath
e numpy
funzionano anche per oggetti complessi, controlleranno se la parte reale o immaginaria è NaN o Infinity.
- Le
numpy
funzioni funzionano anche per numpy
array 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.isposinf
e numpy.isneginf
.
- Pandas offre due funzioni aggiuntive per verificare
NaN
: pandas.isna
e pandas.isnull
(ma non solo NaN, corrisponde anche None
e 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.array
o numpy.array
), il tipo di array deve essere float
o complex
perché 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