Чи можна встановити число на NaN або нескінченність?


202

Чи можна встановити елемент масиву NaNв Python?

Крім того, чи можна встановити змінну до +/- нескінченності? Якщо так, чи є якась функція, щоб перевірити, чи є число нескінченним чи ні?


3
stackoverflow.com/questions/944700 розповідає, як перевірити наявність NaN. Для Inf та -Inf ви можете протестувати з ==, але це не працює для NaN через правила IEEE754 для NaN.
Девід Геффернан

Я думаю, що найнадійнішим способом є використання належних функцій, як isinfі isnanяк це передбачено numpy. Дивіться мою відповідь нижче.
Олів'є Верд'є,

Відповіді:


271

Трансляція з рядка за допомогою float():

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

1
Це навчить мене не стрибати з квочкою, перш ніж читати питання вдруге !! Вибачте! Сказавши це, не завадило б сказати так все одно, бо потрапити в цю пастку легко, NaN! = NaN
Девід Геффернан,

2
також зверніть увагу: >>> float ('Inf') - float ('Inf') ===> nan
ntg

76

Так, ви можете використовувати numpyдля цього.

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
На python> = 2.6, ви можете просто використовувати math.isnan()іmath.isinf()
Agos

8
numpyце досить важкий імпорт, якщо все, що ви хочете, - NaNабоinf
cz

1
Якщо все , що вам потрібно , NaNабо Inf, можна було б from numpy import nan, inf, що проіснувала так як це питання було піднято.
andrewgu

37

Чи можна встановити число на NaN або нескінченність?

Так, насправді існує кілька способів. Деякі працюють без будь-якого імпорту, тоді як інші вимагають import, однак для цієї відповіді я обмежу бібліотеки в огляді стандартними бібліотеками та NumPy (що не стандартна бібліотека, а дуже поширена стороння бібліотека).

Наступна таблиця підсумовує способи, як можна створити не-число чи позитивну чи негативну нескінченність 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    
╘══════════╧══════════════╧════════════════════╧════════════════════╛

Пару зауважень до таблиці:

  • floatКонструктор насправді НЕ чутливий до регістру, тому ви можете також використовувати float("NaN")або float("InFiNiTy").
  • cmathІ numpyконстанти повертають простий Python floatоб'єкти.
  • numpy.NINFФактично єдина константа , я знаю , що не вимагає -.
  • Можна створити складні NaN та Infinity за допомогою complexта 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           
    ╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛
    

    Варіанти з ¹ повернути звичайну float, а не a complex.

чи є якась функція, щоб перевірити, чи є число нескінченним чи ні?

Так, є - насправді є кілька функцій для NaN, Infinity, і ні Nan, ні Inf. Однак ці заздалегідь задані функції не є вбудованими, вони завжди потребують 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     
╘══════════╧═════════════╧════════════════╧════════════════════╛

Ще раз зауваження:

  • Ця cmathта numpyфункція також працює для складних об'єктів, вони будуть перевіряти , якщо реальна чи уявна частина NaN або нескінченність.
  • Ці numpyфункції також працює для numpyмасивів і все , що може бути перетворені в один (наприклад , списки, кортеж і т.д.)
  • Існують також функції, які явно перевіряють на позитивну та негативну нескінченність у NumPy: numpy.isposinfі numpy.isneginf.
  • Pandas пропонує дві додаткові функції для перевірки NaN: pandas.isnaі pandas.isnull(але не тільки NaN, він також відповідає Noneі NaT)
  • Незважаючи на те, що немає вбудованих функцій, їх було б легко створити самостійно (тут я нехтував перевіркою типів та документацією):

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

Для узагальнення очікуваних результатів для цих функцій (якщо припустимо, що вхід є поплавком):

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

Чи можна встановити елемент масиву NaN в Python?

У списку це не проблема, ви завжди можете включити туди NaN (або Infinity):

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

Однак, якщо ви хочете включити його до array(наприклад, array.arrayабо numpy.array), тоді тип масиву повинен бути floatабо complexтому, що в іншому випадку він спробує спустити його до типу масивів!

>>> 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
Примітка: math.isnanне працює зі складними числами. Використовуйте math.isnan(x.real) or math.isnan(x.imag)замість цього.
Джонатан Н

2

Використовуючи Python 2.4, спробуйте

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

Я зіткнувся з проблемою, коли я передавав simplejson на вбудований пристрій, на якому запущений Python 2.4, float("9e999")виправлений. Не використовуйте inf = 9e999, вам потрібно перетворити його з рядка. -infдає -Infinity.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.