Чи можна встановити число на 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.