Làm cách nào để kiểm tra giá trị NaN?


981

float('nan')kết quả trong Nan (không phải là một số). Nhưng làm thế nào để tôi kiểm tra nó? Nên rất dễ dàng, nhưng tôi không thể tìm thấy nó.


20
Để biết một số lịch sử của NaN trong Python, xem PEP 754. python.org/dev/peps/pep-0754
Craig McQueen

Câu trả lời:


1280

math.is Nam (x)

Trả về Truenếu x là NaN (không phải số) và Falsengược lại.

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

5
@ charlie-parker: Trong Python3, math.isnan vẫn là một phần của mô-đun toán học. docs.python.org/3/l Library / math.html # math.isnan . Sử dụng numpy.isnan nếu bạn muốn, câu trả lời này chỉ là một gợi ý.
gimel

2
@ Sitting Bull Xem docs.python.org/3/library/functions.html#float "Nếu đối số là một chuỗi, nó nên chứa một số thập phân", hoặc "Infinity" "inf" "nan"
gimel

35
được math.isnanưa thích hơn np.isnan()?
TMWP

34
@TMWP có thể ... import numpymất khoảng 15 MB RAM, trong khi import mathmất khoảng 0,2 MB
petrpulc

9
@TMWP: Nếu bạn đang sử dụng NumPy, numpy.isnanlà một lựa chọn ưu việt, vì nó xử lý các mảng NumPy. Nếu bạn không sử dụng NumPy, sẽ không có ích gì khi sử dụng phụ thuộc NumPy và dành thời gian để tải NumPy chỉ để kiểm tra NaN (nhưng nếu bạn đang viết loại mã kiểm tra NaN, có thể bạn nên sử dụng NumPy).
user2357112 hỗ trợ Monica

359

Cách thông thường để kiểm tra NaN là xem nó có bằng chính nó không:

def isNaN(num):
    return num != num

8
Lời cảnh báo: trích dẫn bình luận của Bear bên dưới "Dành cho những người mắc kẹt với trăn <= 2.5. Nan! = Nan không hoạt động đáng tin cậy. Thay vào đó, sử dụng numpy." Phải nói rằng, tôi chưa bao giờ thấy nó thất bại.
mavnn

22
Tôi chắc chắn rằng, do quá tải toán tử, có rất nhiều cách tôi có thể nhầm lẫn chức năng này. đi với math.isnan ()
djsadinoff

4
Nó nói trong thông số 754 được đề cập ở trên rằng NaN == NaN phải luôn luôn sai, mặc dù không phải lúc nào nó cũng được thực hiện như vậy. Không thể đây là cách toán học và / hoặc numpy kiểm tra điều này dưới mui xe nào?
Hari Ganesan

Cảm ơn . điều này cũng nhanh hơn 15-20 lần so với sử dụng np.isnan nếu thực hiện thao tác trên vô hướng
thomas.mac

5
Mặc dù điều này hoạt động và, ở một mức độ nào đó có ý nghĩa, tôi là một con người có nguyên tắc và sau đây tôi tuyên bố đây là phù thủy bị cấm. Vui lòng sử dụng math.isnan thay thế.
Gonzalo

152

numpy.isnan(number)cho bạn biết nếu nó NaNhay không.


3
Hoạt động trong phiên bản python 2.7 cũng vậy.
Michel Keijzers

6
numpy.all(numpy.isnan(data_list))cũng hữu ích nếu bạn cần xác định xem tất cả các thành phần trong danh sách có phải là nan hay không
Jay P.

3
Không cần NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc 28/03/2015

6
Khi câu trả lời này được viết 6 năm trước, Python 2.5 vẫn được sử dụng phổ biến - và math.isnan không phải là một phần của thư viện chuẩn. Ngày nay tôi thực sự hy vọng điều đó không xảy ra ở nhiều nơi!
mavnn 30/03/2015

4
lưu ý rằng np.isnan () không xử lý kiểu thập phân. Kiểu tối đa (có nhiều hàm numpy). math.isnan () không xử lý.
comte

55

Dưới đây là ba cách mà bạn có thể kiểm tra một biến là "NaN" hay không.

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

Đầu ra

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

2
pd.isna (giá trị) đã cứu rất nhiều rắc rối! làm việc như một cơ duyên!
thoái vị

1
ps.isna()giải quyết vấn đề của tôi Cảm ơn!
darthbhyrava

32

đây là một câu trả lời làm việc với:

  • Việc triển khai NaN tuân thủ tiêu chuẩn IEEE 754
    • tức là: NaN của python : float('nan'), numpy.nan...
  • bất kỳ đối tượng nào khác: chuỗi hoặc bất cứ điều gì (không đưa ra ngoại lệ nếu gặp phải)

Một NaN được triển khai theo tiêu chuẩn, là giá trị duy nhất mà so sánh bất bình đẳng với chính nó sẽ trả về True:

def is_nan(x):
    return (x != x)

Và một số ví dụ:

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

Đầu ra:

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

1
Chuỗi tôi đang kiểm tra là các chuỗi có giá trị bị thiếu là 'nans' (???) để giải pháp này hoạt động khi các chuỗi khác không thành công.
keithpjcar

numpy.nanlà một floatđối tượng Python thông thường , giống như kiểu được trả về float('nan'). Hầu hết các NaN bạn gặp trong NumPy sẽ không phải là numpy.nanđối tượng.
user2357112 hỗ trợ Monica

numpy.nanxác định giá trị NaN của nó ngày của riêng mình trong thư viện cơ bản trong C . Nó không quấn NaN của trăn. Nhưng hiện tại, cả hai đều tuân thủ tiêu chuẩn IEEE 754 vì họ dựa vào API C99.
x0s

@ user2357112supportsMonica: Python và NaN numpy thực sự không hành xử giống nhau: float('nan') is float('nan')(không duy nhất) và np.nan is np.nan(duy nhất)
x0s

@ x0s: Điều đó không liên quan gì đến NumPy. np.nanlà một đối tượng cụ thể, trong khi mỗi float('nan')cuộc gọi tạo ra một đối tượng mới. Nếu bạn đã làm nan = float('nan'), thì bạn cũng sẽ nhận được nan is nan. Nếu bạn xây dựng một thực tế NumPy NaN với một cái gì đó giống như np.float64('nan'), sau đó bạn sẽ nhận được np.float64('nan') is not np.float64('nan')quá .
user2357112 hỗ trợ Monica

28

Tôi thực sự chỉ gặp phải vấn đề này, nhưng đối với tôi, nó đang kiểm tra nan, -inf hoặc inf. Tôi vừa mới sử dụng

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

Điều này đúng với các số, sai cho nan và cả inf và sẽ đưa ra một ngoại lệ cho những thứ như chuỗi hoặc các loại khác (có lẽ là một điều tốt). Ngoài ra, điều này không yêu cầu nhập bất kỳ thư viện nào như math hay numpy (numpy quá lớn đến nỗi nó tăng gấp đôi kích thước của bất kỳ ứng dụng được biên dịch nào).


9
math.isfiniteđã không được giới thiệu cho đến khi Python 3.2, vì vậy đã đưa ra câu trả lời từ @DaveTheSellectist đã được đăng vào năm 2012, nó không chính xác là "phát minh lại [bánh xe" - giải pháp vẫn là viết tắt của những người làm việc với Python 2.
sudo_coffee

22

math.is Nam ()

hoặc so sánh số lượng với chính nó. NaN luôn luôn là! = NaN, nếu không (ví dụ nếu đó một số) thì việc so sánh sẽ thành công.


6
Đối với những người mắc kẹt với trăn <= 2,5. Nan! = Nan không hoạt động đáng tin cậy. Được sử dụng numpy thay thế.
Gấu

16

Một phương pháp khác nếu bạn bị mắc kẹt trên <2.6, bạn không có numpy và bạn không có hỗ trợ IEEE 754:

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

12

Vâng, tôi đã đăng bài viết này, vì tôi đã gặp một số vấn đề với chức năng:

math.isnan()

Có vấn đề khi bạn chạy mã này:

a = "hello"
math.isnan(a)

Nó làm tăng ngoại lệ. Giải pháp của tôi cho điều đó là thực hiện một kiểm tra khác:

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

3
Có lẽ nó đã bị hạ cấp bởi vì isnan () mất một số float chứ không phải một chuỗi. Không có gì sai với chức năng này, và vấn đề chỉ nằm ở việc anh ta cố gắng sử dụng nó. (Đối với trường hợp sử dụng cụ thể đó, giải pháp của anh ấy là hợp lệ, nhưng đó không phải là câu trả lời cho câu hỏi này.)
Peter Hansen

6
Hãy cẩn thận với việc kiểm tra các loại theo cách này. Điều này sẽ không hoạt động, ví dụ như đối với numpy.float32 NaN. Tốt hơn nên sử dụng thử / ngoại trừ xây dựng: def is_nan(x): try: return math.isnan(x) except: return False
Rob

3
NaN không có nghĩa là một giá trị không phải là một số hợp lệ. Đây là một phần của biểu diễn dấu phẩy động của IEEE để xác định rằng một kết quả cụ thể không được xác định. ví dụ 0 / 0. Do đó, hỏi "xin chào" là nan là vô nghĩa.
Brice M. Dempsey

2
điều này tốt hơn bởi vì NaN có thể hạ cánh trong bất kỳ danh sách chuỗi, số nguyên hoặc số float nào, vì vậy hãy kiểm tra hữu ích
RAFIQ

Tôi đã phải thực hiện chính xác điều này để xử lý các cột chuỗi trong gấu trúc.
Cristian Garcia

7

Với python <2.6 tôi đã kết thúc với

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

Điều này hoạt động với tôi với python 2.5.1 trên hộp Solaris 5.9 và với python 2.6.5 trên Ubuntu 10


6
Điều này không quá dễ mang theo, vì Windows đôi khi gọi điều này-1.#IND
Mike T

5

Tôi đang nhận dữ liệu từ một dịch vụ web gửi NaNdưới dạng chuỗi 'Nan'. Nhưng cũng có thể có các loại chuỗi khác trong dữ liệu của tôi, vì vậy một đơn giản float(value)có thể đưa ra một ngoại lệ. Tôi đã sử dụng biến thể sau đây của câu trả lời được chấp nhận:

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

Yêu cầu:

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

1
hoặctry: int(value)
chwi

@chwi vậy đề nghị của bạn nói về valueviệc có NaNhay không?
Mahdi

Chà, "không phải là số", bất cứ điều gì không thể chuyển sang int tôi đoán thực tế không phải là số và câu lệnh thử sẽ thất bại? Hãy thử, trả lại đúng, ngoại trừ trả lại sai.
chwi

@chwi Vâng, lấy "không phải là một con số" theo nghĩa đen, bạn đúng, nhưng đó không phải là vấn đề ở đây. Trên thực tế, tôi đang tìm kiếm chính xác ngữ nghĩa của NaNnó (như trong python những gì bạn có thể nhận được float('inf') * 0), và do đó, mặc dù chuỗi 'Xin chào' không phải là một số, nhưng nó cũng không phải NaNNaNvẫn là một giá trị số!
Mahdi

@chwi: Bạn đúng, nếu xử lý ngoại lệ là ngoại lệ cụ thể. Nhưng trong câu trả lời này, ngoại lệ chung đã được xử lý. Vì vậy, không cần phải kiểm tra int(value)Đối với tất cả ngoại lệ, Falsesẽ được viết.
Harsha Biyani

3

Tất cả các phương thức để biết biến đó là NaN hay Không:

Không có loại

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

Loại 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

2

Cách xóa (các) mục NaN (float) khỏi danh sách các loại dữ liệu hỗn hợp

Nếu bạn có các loại hỗn hợp trong một lần lặp, đây là một giải pháp không sử dụng 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]

Đánh giá ngắn mạch có nghĩa là isnansẽ không được gọi trên các giá trị không thuộc loại 'float', vì False and (…)nhanh chóng đánh giá Falsemà không phải đánh giá phía bên tay phải.


1

Trong Python 3.6 kiểm tra giá trị chuỗi x math.isnan (x) và np.isnan (x) phát sinh lỗi. Vì vậy, tôi không thể kiểm tra xem giá trị đã cho có phải là NaN hay không nếu tôi không biết trước đó là số. Sau đây dường như để giải quyết vấn đề này

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

1

Có vẻ như kiểm tra nếu nó bằng chính nó

x!=x

là nhanh nhất

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)

0

Đối với nan loại nổi

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

-5

cho chuỗi trong gấu trúc lấy pd.isnull:

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

chức năng trích xuất tính năng cho 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

Điều gì cho việc giảm này?
Max Kleiner

isnull trả về true cho không chỉ các giá trị NaN.
Boris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.