Gán một biến NaN trong python không có numpy


103

Hầu hết các ngôn ngữ đều có hằng số NaN mà bạn có thể sử dụng để gán giá trị NaN cho một biến. Python có thể làm điều này mà không cần sử dụng numpy?


1
C, C ++, java, C #, ocaml, một phần của rất nhiều ngôn ngữ.
zelinka

2
NaN, trong C, là NAN; nó là một hằng số được xác định math.h, kể từ C99. (Tôi cảm thấy thật công bằng khi gọi phiên bản chuẩn hóa gần đây nhất của ngôn ngữ là ngôn ngữ đó. Vì vậy, "C" là C11.) (Xem stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in -c ); trong C ++, nó NANcũng, cũng có nan(), nanf()nanl(), mặc dù tôi là một chút ít chắc chắn về những gì họ làm. double.NaNtrong Java, Double.NaNtrong C #…
Thanatos

Câu trả lời:


168

Có - sử dụng math.nan.

>>> from math import nan
>>> print(nan)
nan
>>> print(nan + 2)
nan
>>> nan == nan
False
>>> import math
>>> math.isnan(nan)
True

Trước Python 3.5, người ta có thể sử dụng float("nan")(phân biệt chữ hoa chữ thường).

Lưu ý rằng việc kiểm tra xem liệu hai thứ có NaN bằng nhau hay không sẽ luôn trả về false. Điều này một phần là do hai thứ "không phải là số" không thể (nói một cách chính xác) là bằng nhau - hãy xem Cơ sở lý luận cho tất cả các so sánh trả về sai cho các giá trị IEEE754 NaN là gì? để biết thêm chi tiết và thông tin.

Thay vào đó, hãy sử dụng math.isnan(...)nếu bạn cần xác định xem một giá trị có phải là NaN hay không.

Hơn nữa, ngữ nghĩa chính xác của ==thao tác trên giá trị NaN có thể gây ra các vấn đề nhỏ khi cố gắng lưu trữ NaN bên trong các loại vùng chứa chẳng hạn như listhoặc dict(hoặc khi sử dụng các loại vùng chứa tùy chỉnh). Xem Kiểm tra sự hiện diện của NaN trong hộp đựng để biết thêm chi tiết.


Bạn cũng có thể tạo số NaN bằng mô-đun thập phân của Python :

>>> from decimal import Decimal
>>> b = Decimal('nan')
>>> print(b)
NaN
>>> print(repr(b))
Decimal('NaN')
>>>
>>> Decimal(float('nan'))
Decimal('NaN')
>>> 
>>> import math
>>> math.isnan(b)
True

math.isnan(...) cũng sẽ hoạt động với các đối tượng Thập phân.


Tuy nhiên, bạn không thể tạo số NaN trong mô-đun phân số của Python :

>>> from fractions import Fraction
>>> Fraction('nan')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 146, in __new__
    numerator)
ValueError: Invalid literal for Fraction: 'nan'
>>>
>>> Fraction(float('nan'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 130, in __new__
    value = Fraction.from_float(numerator)
  File "C:\Python35\lib\fractions.py", line 214, in from_float
    raise ValueError("Cannot convert %r to %s." % (f, cls.__name__))
ValueError: Cannot convert nan to Fraction.

Ngẫu nhiên, bạn cũng có thể làm float('Inf'), Decimal('Inf')hoặc math.inf(3.5+) để gán các số vô hạn. (Và cũng xem math.isinf(...))

Tuy nhiên, làm Fraction('Inf')hoặc Fraction(float('inf'))không được phép và sẽ đưa ra một ngoại lệ, giống như NaN.

Nếu bạn muốn một cách nhanh chóng và dễ dàng để kiểm tra xem một số không phải là NaN hay vô hạn, bạn có thể sử dụng math.isfinite(...)Python 3.2+.


Nếu bạn muốn thực hiện các kiểm tra tương tự với số phức, cmathmô-đun chứa một tập hợp các hàm và hằng số tương tự như mathmô-đun:


2
Lưu ý rằng sử dụng float ('nan) chậm hơn 3 lần so với sử dụng np.nan và chậm hơn khoảng 6,5 lần so với việc gán nan = float (' nan ') một lần và sau đó sử dụng biến' nan 'cho tất cả các phép gán sau (như được đề xuất trong abarnert's câu trả lời).
Daniel Goldfarb

18
nan = float('nan')

Và bây giờ bạn có hằng số nan,.

Tương tự, bạn có thể tạo các giá trị NaN cho số thập phân.

dnan = Decimal('nan')

Đây là câu trả lời hiệu quả nhất cho các phép gán nhiều nan: Nghĩa là, chỉ sử dụng float ('nan') một lần, sau đó sử dụng hằng được gán cho tất cả các phép gán còn lại. Tuy nhiên, nếu bạn chỉ làm một hoặc hai bài tập với tổng số nan, thì sử dụng numpy.nan là nhanh nhất.
Daniel Goldfarb

7

Sử dụng float("nan"):

>>> float("nan")
nan

6

Bạn có thể làm gì float('nan')để có được NaN.


6

Bạn có thể lấy NaN từ "inf - inf" và bạn có thể lấy "inf" từ một số lớn hơn 2e308, vì vậy, tôi thường sử dụng:

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan

3
Câu trả lời này đã phản đối không hợp lý. Tôi đang viết nhiều bài kiểm tra phân tích cú pháp nhỏ trong các tệp .txt và sử dụng ast.literal_eval để có được phần đầu ra mong đợi. Không thể gọi float ('nan') ở đó, và câu trả lời này rất hữu ích cho tôi.
Vitalik Verhovodov

0

Một cách nhất quán hơn (và ít mờ hơn) để tạo inf và -inf là sử dụng lại float ():

>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf

Lưu ý rằng kích thước của phao thay đổi tùy thuộc vào kiến ​​trúc, vì vậy tốt nhất là bạn nên tránh sử dụng các số ma thuật như 9e999, ngay cả khi điều đó có thể hoạt động.

import sys
sys.float_info
sys.float_info(max=1.7976931348623157e+308,
               max_exp=1024, max_10_exp=308,
               min=2.2250738585072014e-308, min_exp=-1021,
               min_10_exp=-307, dig=15, mant_dig=53,
               epsilon=2.220446049250313e-16, radix=2, rounds=1)
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.