如何在 Python Pandas 中比较两个具有缺失值的 DataFrame

pythonserver side programmingprogramming更新于 2026/2/15 2:20:17

简介

Pandas 使用 NumPy NaN (np.nan) 对象来表示缺失值。此 Numpy NaN 值具有一些有趣的数学属性。例如,它不等于其自身。但是,Python None 对象与自身进行比较时计算结果为 True。

如何做到这一点..

让我们看一些示例来了解 np.nan 的行为方式。

import pandas as pd
import numpy as np

# Python None 对象与自身进行比较。
print(f"输出 \n *** {None == None} ")

输出

*** True


# Numpy nan 与自身进行比较。
print(f"输出 \n *** {np.nan == np.nan} ")

输出

*** False


# nan 是否大于 10 或 1000?
print(f"Output \n *** {np.nan > 10} ")

输出

*** False

传统上,Series 和 DataFrames 使用等号运算符 == 进行比较。比较的结果是一个对象。让我们首先看看如何使用等号运算符。

# 创建一个包含网球运动员及其大满贯头衔的数据框。
df = pd.DataFrame(data={"players": ['Federer', 'Nadal', 'Djokovic', 'Murray','Medvedev','Zverev'],
"titles": [20, 19, 17, 3,np.nan,np.nan]})
# 设置索引
df.index = df['players']

# 按升序对索引进行排序
df.sort_index(inplace=True, accending=True)

# 检查索引是否已设置
df.index.is_monotonic_increasing

# 查看记录
print(f"输出\n{df}")

输出

         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. 为了更好地理解,我们首先将所有球员与标量值"费德勒"进行比较,然后查看结果。

print(f'Output \n {df == "Federer"}')

输出

          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. 这种方法按预期工作,但每当您尝试比较具有缺失值的 DataFrames 时,就会出现问题。为了观察这一点,让我们将 df 与自身进行比较。

df_compare = df == df
print(f'Output \n {df_compare}')

输出

players titles
players
Djokovic True True
Federer True True
Medvedev True False
Murray True True
Nadal True True
Zverev True False

3. 乍一看,所有值似乎都是正确的,正如您所期望的那样。但是,使用 .all 方法查看每列是否仅包含 True 值(因为我们正在比较两个相似的对象,所以应该是这样,对吧?)会产生意想不到的结果。

print(f'Output \n {df_compare.all()}')

输出

players True
titles False
dtype: bool

4.如前面的注释中所述,发生这种情况是因为缺失值无法平等地相互比较。看,我们清楚地知道梅德韦杰夫和兹维列夫没有头衔(即 NaN),因此如果我们将每列中缺失值的数量相加,我们应该得到头衔的值为 2,球员的值为 0。让我们看看会发生什么。

print(f'Output \n {(df_compare == np.nan).sum()}')

输出

players 0
titles 0
dtype: int64

5. 上述结果是出乎意料的,因为 nan 的行为非常不同。

6.将两个完整的 DataFrames 相互比较的正确方法不是使用等号运算符 (==),而是使用 .equals 方法。

此方法将位于同一位置的 NaN 视为相等。

需要注意的是,.eq 方法相当于 == 而不是 .equals。

print(f'Output \n {df_compare.equals(df_compare)}')

输出

True

7. 如果您尝试在单元测试中比较两个 DataFrames,还有另一种方法。如果两个 DataFrames 不相等,assert_frame_equal 函数会引发 AssertionError。如果两个 DataFrames 相等,则返回 None。

from pandas.testing import assert_frame_equal
print(f'Output \n {assert_frame_equal(df_compare, df_compare) is None}')

输出

True

相关文章


有用资源