É possível definir um número para NaN ou infinito?

203

É possível definir um elemento de uma matriz NaNem Python?

Além disso, é possível definir uma variável para +/- infinito? Nesse caso, existe alguma função para verificar se um número é infinito ou não?

Prumo
fonte
3
stackoverflow.com/questions/944700 informa como verificar o NaN. Para Inf e -Inf, você pode testar com ==, mas isso não funciona para o NaN por causa das regras IEEE754 para o NaN.
David Heffernan
Eu acho que a maneira mais confiável é usar funções apropriadas como isinfe isnanconforme fornecido por numpy. Veja minha resposta abaixo.
precisa

Respostas:

272

Transmitir da string usando float():

>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False
moinudin
fonte
1
Isso vai me ensinar a não dar uma piada antes de ler a pergunta pela segunda vez !! Desculpe! Dito isto, não faria mal para dizer isso tudo a mesma coisa, porque isso é uma armadilha fácil de cair, NaN = NaN!
David Heffernan
2
observe também: >>> float ('Inf') - float ('Inf') ===> nan
ntg
76

Sim, você pode usar numpypara isso.

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
fonte
21
No python> = 2.6, você pode apenas usar math.isnan()emath.isinf()
Agos
8
numpyé bastante uma importação pesado se tudo que você quer é NaNouinf
CZ
1
Se tudo que você precisa é NaNou Inf, alguém poderia from numpy import nan, infexistir desde que essa questão foi levantada.
andrewgu 27/02/19
37

É possível definir um número para NaN ou infinito?

Sim, de fato, existem várias maneiras. Alguns funcionam sem nenhuma importação, enquanto outros exigem import, no entanto, para esta resposta, limitarei as bibliotecas da visão geral à biblioteca padrão e ao NumPy (que não é uma biblioteca padrão, mas uma biblioteca de terceiros muito comum).

A tabela a seguir resume as maneiras pelas quais se pode criar um infinito não-numérico ou positivo ou 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    
╘══════════╧══════════════╧════════════════════╧════════════════════╛

Algumas observações para a mesa:

  • O floatconstrutor não diferencia maiúsculas de minúsculas, então você também pode usar float("NaN")or float("InFiNiTy").
  • As constantes cmathe numpyretornam floatobjetos Python simples .
  • Na numpy.NINFverdade, é a única constante que conheço que não requer o -.
  • É possível criar NaN e Infinity complexos com 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           
    ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛

    As opções com ¹ retornam uma planície float, não a complex.

existe alguma função para verificar se um número é infinito ou não?

Sim, existe - de fato, existem várias funções para NaN, Infinity e nem Nan nem Inf. No entanto, essas funções predefinidas não são internas, elas sempre exigem um 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     
╘══════════╧═════════════╧════════════════╧════════════════════╛

Novamente, algumas observações:

  • O cmathenumpy funções também funcionam para objetos complexos; eles verificarão se a parte real ou imaginária é NaN ou Infinity.
  • As numpyfunções também funcionam para numpymatrizes e tudo o que pode ser convertido em uma (como listas, tupla, etc.)
  • Também existem funções que verificam explicitamente o infinito positivo e negativo no NumPy: numpy.isposinfe numpy.isneginf.
  • O Pandas oferece duas funções adicionais a serem verificadas NaN: pandas.isnae pandas.isnull(mas não apenas o NaN, ele também combina Nonee NaT)
  • Mesmo que não existam funções internas, seria fácil criá-las você mesmo (negligenciei a verificação e a documentação do tipo aqui):

    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 os resultados esperados para essas funções (assumindo que a entrada seja flutuante):

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

É possível definir um elemento de uma matriz para NaN em Python?

Em uma lista, não há problema, você sempre pode incluir NaN (ou Infinity) lá:

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

No entanto, se você quiser incluí-lo em um array(por exemplo array.arrayou numpy.array), o tipo da matriz deve ser floatou complexporque, caso contrário, tentará fazer o downcast para o tipo de matrizes!

>>> 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
fonte
1
Nota: math.isnannão funciona com números complexos. Use em math.isnan(x.real) or math.isnan(x.imag)vez disso.
Jonathan H
2

Ao usar o Python 2.4, tente

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

Estou enfrentando o problema quando estava portando o simplejson para um dispositivo incorporado que executava o Python 2.4, o float("9e999")corrigiu. Não use inf = 9e999, você precisa convertê-lo de string. -infdá o -Infinity.


fonte