Sự khác biệt giữa NaN và None là gì?


94

Tôi đang đọc hai cột của tệp csv bằng cách sử dụng gấu trúc readcsv()và sau đó gán giá trị cho từ điển. Các cột chứa các chuỗi số và chữ cái. Đôi khi có trường hợp một ô trống. Theo tôi, giá trị được đọc cho mục từ điển đó nên được gán Nonenhưng thay vào đó nanđược gán. Chắc chắn Nonelà mô tả nhiều hơn về một ô trống vì nó có giá trị null, trong khi nanchỉ nói rằng giá trị được đọc không phải là một số.

Sự hiểu biết của tôi có đúng không, sự khác biệt giữa Nonevà là nangì? Tại sao được nanchỉ định thay vì None?

Ngoài ra, từ điển của tôi kiểm tra bất kỳ ô trống nào đã được sử dụng numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Nhưng điều này mang lại cho tôi một lỗi nói rằng tôi không thể sử dụng kiểm tra này cho v. Tôi đoán đó là vì một số nguyên hoặc biến float, không phải là một chuỗi được sử dụng. Nếu điều này là đúng, làm cách nào tôi có thể kiểm tra vmột "ô trống" / nantrường hợp?


Văn bản qwertykhông phải là một con số.
Robert Harvey

1
@RobertHarvey Tôi biết, vì vậy chắc chắn Nonesẽ là một mô tả tốt hơn về giá trị của một ô trống.
user1083734

Câu trả lời:


107

NaN được sử dụng như một trình giữ chỗ cho dữ liệu bị thiếu một cách nhất quán trong gấu trúc , tính nhất quán là tốt. Tôi thường đọc / dịch NaN là "mất tích" . Cũng xem phần 'làm việc với dữ liệu bị thiếu' trong tài liệu.

Wes viết trong tài liệu 'lựa chọn đại diện NA' :

Sau nhiều năm sử dụng trong sản xuất [NaN], ít nhất theo quan điểm của tôi, đã được chứng minh là quyết định tốt nhất dựa trên tình hình hoạt động của NumPy và Python nói chung. Giá trị đặc biệt NaN (Not-A-Number) được sử dụng ở mọi nơi làm giá trị NA và có các hàm API isnullnotnullcó thể được sử dụng trên các kiểu để phát hiện giá trị NA.
...
Do đó, tôi đã chọn phương pháp tiếp cận "tính thực tế đánh bại độ tinh khiết" của Pythonic và giao dịch khả năng số nguyên NA cho một cách tiếp cận đơn giản hơn nhiều là sử dụng một giá trị đặc biệt trong mảng đối tượng và float để biểu thị NA, và thúc đẩy mảng số nguyên thành nổi khi NA phải là đã giới thiệu.

Lưu ý: "gotcha" mà Chuỗi số nguyên chứa dữ liệu bị thiếu được upcast để thả nổi .

Theo ý kiến ​​của tôi, lý do chính để sử dụng NaN (trên Không) là nó có thể được lưu trữ với loại float64 của numpy, thay vì loại đối tượng kém hiệu quả hơn, hãy xem quảng cáo loại NA .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff bình luận (bên dưới) về điều này:

np.nancho phép các hoạt động được vector hóa; của nó là một giá trị float, trong khi Nonetheo định nghĩa, buộc kiểu đối tượng, về cơ bản vô hiệu hóa tất cả hiệu quả trong numpy.

Vì vậy, lặp lại nhanh 3 lần: object == bad, float == good

Nói vậy, nhiều thao tác có thể vẫn hoạt động tốt với None vs NaN (nhưng có lẽ không được hỗ trợ, tức là đôi khi chúng có thể cho kết quả đáng ngạc nhiên ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Để trả lời câu hỏi thứ hai:
Bạn nên sử dụng pd.isnullpd.notnullkiểm tra dữ liệu bị thiếu (NaN).


19
chỉ cần thêm 2c ở đây .... np.nancho phép các hoạt động được vector hóa; giá trị float một mình, trong khi Nonetheo định nghĩa lực lượng objectchủng loại, và về cơ bản vô hiệu hóa tất cả các hiệu quả trong NumPy, vì vậy lặp lại 3 lần nhanh:object==bad, float==good
Jeff

1
<NA>cũng là một np.nan?
Gathide

18

NaNcó thể được sử dụng như một giá trị số trong các phép toán, trong khi Nonekhông thể (hoặc ít nhất là không nên).

NaNlà một giá trị số, như được định nghĩa trong tiêu chuẩn dấu phẩy động IEEE 754 . Nonelà một kiểu Python nội bộ ( NoneType) và sẽ giống như "không tồn tại" hoặc "trống" hơn là "không hợp lệ về số lượng" trong ngữ cảnh này.

"Triệu chứng" chính của điều đó là, nếu bạn thực hiện, chẳng hạn, một trung bình hoặc một tổng trên một mảng chứa NaN, thậm chí là một giá trị duy nhất, kết quả là bạn sẽ nhận được NaN ...

Mặt khác, bạn không thể thực hiện các phép toán sử dụng Nonelàm toán hạng.

Vì vậy, tùy từng trường hợp, bạn có thể sử dụng Nonenhư một cách để yêu cầu thuật toán của bạn không xem xét các giá trị không hợp lệ hoặc không tồn tại trên các phép tính. Điều đó có nghĩa là thuật toán nên kiểm tra từng giá trị để xem nó có đúng không None.

Numpy có một số chức năng để tránh các giá trị NaN làm ảnh hưởng đến kết quả của bạn, chẳng hạn như nansumnan_to_numchẳng hạn.


Tôi đồng ý với bạn rằng Không nên được sử dụng cho các mục nhập không tồn tại, vậy tại sao lại df=pd.readcsv('file.csv')cho tôi NaNgiá trị cho các ô trống mà không phải None? Theo như tôi biết, pd.DataFrames không dành riêng cho số.
user1083734

Chà, nó có thể là một sự lựa chọn thiết kế. Tôi cho rằng DataFrames và Series có a dtype, vì vậy các giá trị không hợp lệ của dtype=floatphải được biểu thị bằng các giá trị số, có NaNNonekhông phải ( Nonelà của NoneType).
heltonbiker,

Ngoài ra, nhiều phương thức Pandas có một nađối số, cho phép bạn quyết định giá trị nào bạn sẽ sử dụng để thay thế các giá trị không có sẵn
heltonbiker

Được rồi cảm ơn. Vì vậy, tôi không thực sự đọc các số vào DataFrame của mình, mà là các chuỗi số và chữ cái. Tôi nên sử dụng loại kiểm tra nào để phát hiện các ô trống? Một tấm séc như thế nào; nếu dtype == float: ??
user1083734,

Có lẽ đăng một mẫu dữ liệu CSV của bạn sẽ hữu ích. Tôi có thể tưởng tượng rằng, nếu có chuỗi, thì dtype sẽ là chuỗi cho toàn bộ cột (Series). Nhưng có lẽ nếu không phải mọi hàng đều có cùng số cột, bạn sẽ có dữ liệu không có sẵn. Tôi nghĩ bạn sẽ phải kiểm tra điều đó.
heltonbiker

3

Hàm isnan()kiểm tra xem một thứ có phải là "Không phải là Số" hay không và sẽ trả về liệu một biến có phải là số hay không, ví dụ: isnan(2)sẽ trả về false

Các điều kiện myVar is not Nonetrả về cho dù biến có được xác định hay không

Mảng numpy của bạn sử dụng isnan()vì nó được dự định là một mảng số và nó khởi tạo tất cả các phần tử của mảng thành NaNcác phần tử này được coi là "trống"


1
Tôi nghĩ isnan(2)sẽ quay trở lại False, vì 2 không phải là NaN.
heltonbiker

Ngoài ra, numpy.emptykhông khởi tạo giá trị mảng thành NaN. Nó chỉ đơn giản là không khởi tạo các giá trị.
heltonbiker

5
Kiểm tra thích hợp cho None-ness là myVar is not None, không myVar != None.
Jaime

3
Lưu ý rằng điều đó np.isnan()không được triển khai cho các biến chuỗi, vì vậy nếu bạn chuyển nó một chuỗi, nó sẽ bị lỗi. Tốt hơn nên sử dụng pd.isnullcái nào hoạt động với chuỗi.
Michael

-1

Dưới đây là sự khác biệt:

  • nan thuộc về lớp float
  • None thuộc về lớp NoneType

Tôi thấy bài viết dưới đây rất hữu ích: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31


Mặc dù liên kết này có thể trả lời câu hỏi, nhưng tốt hơn hết bạn nên đưa các phần thiết yếu của câu trả lời vào đây và cung cấp liên kết để tham khảo. Các câu trả lời chỉ có liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ đánh giá
A. Kootstra

@ A.Kootstra Tôi hiểu
eswara amirthan s

-3

NaNstants KHÔNG PHẢI là số .
Nonecó thể đại diện cho bất kỳ .

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.