Как я могу проверить значения NaN?

float('nan') результаты в Nan (не число). Но как я могу проверить это? Должно быть очень легко, но я не могу его найти.

19 ответов

Решение

math.isnan()

Проверяет, является ли число с плавающей точкой Na (не числом). NaN являются частью стандартов IEEE 754. Операция, подобная, но не ограничиваясь, inf * 0, inf / inf или любая операция, включающая NaN, например, nan * 1, возвращает NaN.

Новое в версии 2.6.

>>> import math
>>> x=float('nan')
>>> math.isnan(x)
True
>>> 

Обычный способ проверить NaN - посмотреть, равен ли он самому себе:

def isNaN(num):
    return num != num

numpy.isnan(number) говорит вам, если это NaN или нет в Python 2.5.

Вот три способа, где вы можете проверить переменную "NaN" или нет.

import pandas as pd
import numpy as np
import math

#For single variable all three libraries return single boolean
x1 = float("nan")

print(f"It's pd.isna  : {pd.isna(x1)}")
print(f"It's np.isnan  : {np.isnan(x1)}")
print(f"It's math.isnan : {math.isnan(x1)}")

Выход

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True

Кажется, что проверка, равен ли он самому себе

x!=x

самый быстрый.

import pandas as pd 
import numpy as np 
import math 

x = float('nan')

%timeit x!=x                                                                                                                                                                                                                        
44.8 ns ± 0.152 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit math.isnan(x)                                                                                                                                                                                                               
94.2 ns ± 0.955 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit pd.isna(x) 
281 ns ± 5.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.isnan(x)                                                                                                                                                                                                                 
1.38 µs ± 15.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Вот ответ, работающий с:

  • Python неуникальный NaN: float('nan')
  • NumPy уникальный NaN (синглтон): np.nan
  • любые другие объекты: строка или что-то еще (не вызывает исключений, если встречаются)

Вот:

import numpy as np

def is_nan(x):
    return (x is np.nan or x != x)

И несколько примеров:

values = [float('nan'), np.nan, 55, "string", lambda x : x]
for value in values:
    print "{:<8} : {}".format(repr(value), is_nan(value))

Выход:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False

Я на самом деле просто столкнулся с этим, но для меня это была проверка для nan, -inf или inf. Я просто использовал

if float('-inf') < float(num) < float('inf'):

Это верно для чисел, false для nan и обоих inf, и вызовет исключение для таких вещей, как строки или другие типы (что, вероятно, хорошо). Также это не требует импорта каких-либо библиотек, таких как математика или numpy (numpy настолько чертовски большой, что удваивает размер любого скомпилированного приложения).

math.isnan()

или сравните число с собой. NaN всегда!= NaN, в противном случае (например, если это число) сравнение должно быть успешным.

Ну, я вошел в этот пост, потому что у меня были некоторые проблемы с функцией:

math.isnan()

Есть проблема, когда вы запускаете этот код:

a = "hello"
math.isnan(a)

Это вызывает исключение. Мое решение для этого состоит в том, чтобы сделать еще одну проверку:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)

Другой метод, если вы застряли на <2.6, у вас нет numpy, и у вас нет поддержки IEEE 754:

def isNaN(x):
    return str(x) == str(1e400*0)

С питоном < 2.6 я закончил с

def isNaN(x):
    return str(float(x)).lower() == 'nan'

Это работает для меня с python 2.5.1 на коробке Solaris 5.9 и с python 2.6.5 на Ubuntu 10

Сравнение и их гибкость при работе с разными типами объектов.

The table below shows if the type of object can be checked with the given method:

      
+------------+-----+---------+------+--------+------+
|   Method   | NaN | numeric | None | string | list |
+------------+-----+---------+------+--------+------+
| pd.isna    | yes | yes     | yes  | yes    | yes  |
| math.isnan | yes | yes     | no   | no     | no   |
| np.isnan   | yes | yes     | no   | no     | yes  | <-- # will error on mixed type list
+------------+-----+---------+------+--------+------+

The most flexible method to check for all kinds of missing values.


None of the answers cover the flexibility of . While math.isnan and np.isnan will return True for NaN values, you cannot check for different type of objects like None or strings. Both methods will return an error, so checking a list with mixed types will be cumbersom. This while pd.isna is flexible and will return the correct boolean for different kind of types:

      In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: missing_values = [3, None, np.NaN, pd.NA, pd.NaT, '10']

In [4]: pd.isna(missing_values)
Out[4]: array([False,  True,  True,  True,  True, False])

Я получаю данные от веб-службы, которая отправляет NaN как строка 'Nan', Но в моих данных могут быть и другие виды строк, поэтому float(value) может бросить исключение. Я использовал следующий вариант принятого ответа:

def isnan(value):
  try:
      import math
      return math.isnan(float(value))
  except:
      return False

Требование:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True

Все методы, чтобы определить, является ли переменная NaN или нет:

Ни один тип

In [1]: from numpy import math

In [2]: a = None
In [3]: not a
Out[3]: True

In [4]: len(a or ()) == 0
Out[4]: True

In [5]: a == None
Out[5]: True

In [6]: a is None
Out[6]: True

In [7]: a != a
Out[7]: False

In [9]: math.isnan(a)
Traceback (most recent call last):
  File "<ipython-input-9-6d4d8c26d370>", line 1, in <module>
    math.isnan(a)
TypeError: a float is required

In [10]: len(a) == 0
Traceback (most recent call last):
  File "<ipython-input-10-65b72372873e>", line 1, in <module>
    len(a) == 0
TypeError: object of type 'NoneType' has no len()

Тип NaN

In [11]: b = float('nan')
In [12]: b
Out[12]: nan

In [13]: not b
Out[13]: False

In [14]: b != b
Out[14]: True

In [15]: math.isnan(b)
Out[15]: True

Как удалить NaN (float) элемент (ы) из списка смешанных типов данных

Если вы смешали типы в итерируемом, вот решение, которое не использует numpy:

from math import isnan

Z = ['a','b', float('NaN'), 'd', float('1.1024')]

[x for x in Z if not (
                      type(x) == float # let's drop all float values…
                      and isnan(x) # … but only if they are nan
                      )]
['a', 'b', 'd', 1.1024]

Оценка короткого замыкания означает, что isnan не будет вызываться для значений, которые не относятся к типу 'float' как (False and … быстро оценивает False без необходимости оценивать правую сторону.

В Python 3.6 проверка строкового значения x math.isnan(x) и np.isnan(x) вызывает ошибку. Поэтому я не могу проверить, является ли данное значение NaN или нет, если я не знаю заранее, что это число. Следующее, кажется, решает эту проблему

if str(x)=='nan' and type(x)!='str':
    print ('NaN')
else:
    print ('non NaN')

Для нан типа float

>>> import pandas as pd
>>> value = float(nan)
>>> type(value)
>>> <class 'float'>
>>> pd.isnull(value)
True
>>>
>>> value = 'nan'
>>> type(value)
>>> <class 'str'>
>>> pd.isnull(value)
False

Если вы хотите проверить значения, отличные от NaN , отмените все, что используется для пометки NaN; pandas имеет собственную специальную функцию для пометки значений, отличных от NaN.

      lst = [1, 2, float('nan')]

m1 = [e == e for e in lst]              # [True, True, False]

m2 = [not math.isnan(e) for e in lst]   # [True, True, False]

m3 = ~np.isnan(lst)                     # array([ True,  True, False])

m4 = pd.notna(lst)                      # array([ True,  True, False])

Это особенно полезно, если вы хотите отфильтровать значения, отличные от NaN. Для объектов ndarray/Series:==векторизован, поэтому его также можно использовать.

      s = pd.Series(lst)
arr = np.array(lst)

x = s[s.notna()]
y = s[s==s]                             # `==` is vectorized
z = arr[~np.isnan(arr)]                 # array([1., 2.])

assert (x == y).all() and (x == z).all()

Для строк в панде беру pd.isnull:

if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):

функция как извлечение признаков для NLTK

def act_features(atext):
features = {}
if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):
    if word not in default_stopwords:
      features['cont({})'.format(word.lower())]=True
return features
Другие вопросы по тегам