Можно ли установить число в NaN или бесконечность?

203

Можно ли установить элемент массива NaNв Python?

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

боб
источник
3
stackoverflow.com/questions/944700 рассказывает, как проверить наличие NaN. Для Inf и -Inf вы можете протестировать с ==, но это не работает для NaN из-за правил IEEE754 для NaN.
Дэвид Хеффернан
Я думаю, что самый надежный способ - это использовать правильные функции, как isinfи isnanкак предусмотрено numpy. Смотрите мой ответ ниже.
Оливье Вердиер,

Ответы:

272

Приведение из строки с использованием float():

>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False
moinudin
источник
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который существовал после того, как этот вопрос был поднят.
Андрей
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возвращают простые floatобъекты Python .
  • На 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
MSeifert
источник
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.


источник