Est-il possible de définir un nombre à NaN ou à l'infini?


203

Est-il possible de définir un élément d'un tableau NaNen Python?

De plus, est-il possible de définir une variable sur +/- infini? Si oui, existe-t-il une fonction pour vérifier si un nombre est infini ou non?


3
stackoverflow.com/questions/944700 vous indique comment vérifier la présence de NaN. Pour Inf et -Inf, vous pouvez tester avec == mais cela ne fonctionne pas pour NaN en raison des règles IEEE754 pour NaN.
— David Heffernan

Je pense que le moyen le plus fiable consiste à utiliser les fonctions appropriées comme isinfet telles isnanque fournies par numpy. Voir ma réponse ci-dessous.
— Olivier Verdier

Réponses:


272

Cast à partir d'une chaîne en utilisant float():

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

1
Cela m'apprendra à ne pas sauter dessus avant de lire la question une deuxième fois !! Désolé! Cela dit, cela ne ferait pas de mal de le dire tout de même car c'est un piège facile à tomber, NaN! = NaN
— David Heffernan

2
notez également: >>> float ('Inf') - float ('Inf') ===> nan
— ntg

76

Oui, vous pouvez l'utiliser numpypour cela.

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
Sur python> = 2.6, vous pouvez simplement utiliser math.isnan()etmath.isinf()
— Agos

8
numpyest une importation assez lourde si tout ce que vous voulez est NaNouinf
— cz

1
Si tout ce dont vous avez besoin est NaNou Inf, celui from numpy import nan, infqui pourrait exister depuis que cette question a été soulevée.
— andrewgu

37

Est-il possible de définir un nombre à NaN ou à l'infini?

Oui, en fait, il existe plusieurs façons. Quelques-uns fonctionnent sans aucune importation, tandis que d'autres nécessitent import, mais pour cette réponse, je limiterai les bibliothèques de l'aperçu à la bibliothèque standard et à NumPy (qui n'est pas une bibliothèque standard mais une bibliothèque tierce très courante).

Le tableau suivant résume les façons dont on peut créer un infini pas un nombre ou un infini positif ou négatif 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    │
╘══════════╧══════════════╧════════════════════╧════════════════════╛

Quelques remarques sur la table:

  • Le floatconstructeur est en fait insensible à la casse, vous pouvez donc également utiliser float("NaN")ou float("InFiNiTy").
  • Les constantes cmathet numpyrenvoient des floatobjets Python simples .
  • Le numpy.NINFest en fait la seule constante que je connaisse qui ne nécessite pas le -.
  • Il est possible de créer des NaN et Infinity complexes avec complexet 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           │
    ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛

    Les options avec ¹ renvoient une plaine float, pas un complex.

existe-t-il une fonction pour vérifier si un nombre est infini ou non?

Oui, il existe - en fait, il existe plusieurs fonctions pour NaN, Infinity et ni Nan ni Inf. Cependant, ces fonctions prédéfinies ne sont pas intégrées, elles nécessitent toujours 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     │
╘══════════╧═════════════╧════════════════╧════════════════════╛

Encore quelques remarques:

  • Les fonctions cmathet numpyfonctionnent également pour les objets complexes, elles vérifieront si la partie réelle ou imaginaire est NaN ou Infinity.
  • Les numpyfonctions fonctionnent également pour les numpytableaux et tout ce qui peut être converti en un (comme les listes, les tuples, etc.)
  • Il existe également des fonctions qui vérifient explicitement l'infini positif et négatif dans NumPy: numpy.isposinfet numpy.isneginf.
  • Pandas propose deux fonctions supplémentaires à vérifier NaN: pandas.isnaet pandas.isnull(mais pas seulement NaN, il correspond également à Noneet NaT)
  • Même s'il n'y a pas de fonctions intégrées, il serait facile de les créer vous-même (j'ai négligé la vérification de type et la documentation ici):

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

Pour résumer les résultats attendus pour ces fonctions (en supposant que l'entrée est un flottant):

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

Est-il possible de définir un élément d'un tableau sur NaN en Python?

Dans une liste ce n'est pas un problème, vous pouvez toujours y inclure NaN (ou Infinity):

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

Cependant, si vous souhaitez l'inclure dans un array(par exemple array.arrayou numpy.array), le type du tableau doit être floatou complexparce que sinon, il essaiera de le convertir en type de tableaux!

>>> 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
Remarque: math.isnanne fonctionne pas avec des nombres complexes. Utilisez math.isnan(x.real) or math.isnan(x.imag)plutôt.
— Jonathan H

2

Lorsque vous utilisez Python 2.4, essayez

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

Je suis confronté au problème lorsque je portais le simplejson sur un périphérique intégré qui exécutant Python 2.4, l'a float("9e999")corrigé. Ne l'utilisez pas inf = 9e999, vous devez le convertir à partir d'une chaîne. -infdonne le -Infinity.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.