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


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

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

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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.