Computer >> Máy Tính >  >> Lập trình >> Python

Cách so sánh hai DataFrames trong Python Pandas có giá trị bị thiếu

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