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?

Bob
la source
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
moinudin
la source
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
Olivier Verdier
la source
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
MSeifert
la source
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.


la source