Giới thiệu
Pandas sử dụng đối tượng NumPy NaN (np.nan) để biểu thị một giá trị bị thiếu. Giá trị Numpy NaN này có một số tính chất toán học thú vị. Ví dụ, nó không bằng chính nó. Tuy nhiên, không đối tượng Python nào đánh giá là True khi so sánh với chính nó.
Cách thực hiện ..
Hãy để chúng tôi xem một số ví dụ để hiểu cách np.nan hoạt động.
import pandas as pd import numpy as np # Python None Object compared against self. print(f"Output \n *** {None == None} ")
Đầu ra
*** True
# Numpy nan compared against self. print(f"Output \n *** {np.nan == np.nan} ")
Đầu ra
*** False
# Is nan > 10 or 1000 ? print(f"Output \n *** {np.nan > 10} ")
Đầu ra
*** False
Theo truyền thống, Series và DataFrames sử dụng toán tử bằng, ==, để so sánh. Kết quả của các phép so sánh là một đối tượng. Đầu tiên chúng ta hãy xem cách sử dụng toán tử bằng.
# create a dataframe with tennis players and their grandslam titles. df = pd.DataFrame(data={"players": ['Federer', 'Nadal', 'Djokovic', 'Murray','Medvedev','Zverev'], "titles": [20, 19, 17, 3,np.nan,np.nan]}) # set the index df.index = df['players'] # sort the index in ascending df.sort_index(inplace=True, ascending=True) # check if the index is set df.index.is_monotonic_increasing # see records print(f"Output \n{df}")
Đầu ra
players titles players Djokovic Djokovic 17.0 Federer Federer 20.0 Medvedev Medvedev NaN Murray Murray 3.0 Nadal Nadal 19.0 Zverev Zverev NaN
1. Để hiểu rõ hơn, trước tiên chúng ta sẽ so sánh tất cả các tay vợt với một giá trị vô hướng "Federer" và xem kết quả.
print(f'Output \n {df == "Federer"}')
Đầu ra
players titles players Djokovic False False Federer True False Medvedev False False Murray False False Nadal False False Zverev False False
C:\Users\sasan\anaconda3\lib\site-packages\pandas\core\ops\array_ops.py:253: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison res_values = method(rvalues)
2. Điều này hoạt động như mong đợi nhưng trở thành vấn đề bất cứ khi nào bạn cố gắng so sánh DataFrames với các giá trị bị thiếu. Để quan sát điều này, chúng ta hãy so sánh df với bản thân.
df_compare = df == df print(f'Output \n {df_compare}')
Đầu ra
players titles players Djokovic True True Federer True True Medvedev True False Murray True True Nadal True True Zverev True False
3. Thoạt nhìn, tất cả các giá trị có vẻ đúng như bạn mong đợi. Tuy nhiên, hãy sử dụng phương thức .all để xem liệu mỗi cột chỉ chứa giá trị True (vì nó giống như chúng ta đang so sánh hai đối tượng giống nhau phải không?) Mang lại kết quả không mong muốn.
print(f'Output \n {df_compare.all()}')
Đầu ra
players True titles False dtype: bool
4.Như đã đề cập trong các ghi chú trước đó, điều này xảy ra vì các giá trị bị thiếu không so sánh ngang bằng với nhau. Hãy xem, chúng ta biết rõ ràng rằng medvedev và Zverev không có danh hiệu (tức là NaN), vì vậy nếu chúng ta thêm số giá trị còn thiếu trong mỗi cột, chúng ta sẽ nhận được giá trị 2 cho danh hiệu và 0 cho người chơi. Hãy để chúng tôi xem điều gì sẽ xảy ra.
print(f'Output \n {(df_compare == np.nan).sum()}')
Đầu ra
players 0 titles 0 dtype: int64
5. Kết quả của ABove thật bất ngờ vì nan hành xử rất khác.
6. Cách chính xác để so sánh toàn bộ hai DataFrame với nhau không phải bằng toán tử bằng (==) mà bằng phương thức .equals.
Phương pháp này xử lý các NaN ở cùng vị trí là bằng nhau.
Một lưu ý quan trọng là phương thức .eq tương đương với ==không phải .equals.
print(f'Output \n {df_compare.equals(df_compare)}')
Đầu ra
True
7. Cũng có một cách thực hiện khác nếu bạn đang cố gắng so sánh hai DataFrame như một phần của thử nghiệm đơn vị của mình. Hàm khẳng định_frame_equal tạo ra lỗi AssertionError nếu hai DataFrame không bằng nhau. Nó trả về Không có nếu hai DataFrames bằng nhau.
from pandas.testing import assert_frame_equal print(f'Output \n {assert_frame_equal(df_compare, df_compare) is None}')
Đầu ra
True