如何使用Python Pandas比较带有缺失值的两个数据框(DataFrames)

如何使用Python Pandas比较带有缺失值的两个数据框(DataFrames)

介绍

Pandas使用NumPy NaN(np.nan)对象来表示缺失值。这个Numpy NaN值具有一些有趣的数学属性。例如,它不等于它本身。然而,Python None对象在与自身比较时评估为True。

如何实现

让我们看一些例子,以了解np.nan的行为。

import pandas as pd
import numpy as np

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

输出结果

*** True
# Numpy nan与自身比较。
print(f" Output \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, ascending=True)

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

# 查看记录
print(f" Output \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. 为了更好地理解,我们首先将所有球员与标量值”Federer”进行比较,看看结果。

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.正如早期的指出的,这是因为缺失值不相互比较。我们清楚地知道medvedev和Zverev没有冠军(即NaN),因此,如果我们将每列中的缺失值数量相加,应该得到titles为2,players为0的值。让我们看看会发生什么。

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

输出结果

players   0
titles    0
dtype: int64

5. 上述结果是意想不到的,因为nan的行为非常不同。

6. 对于比较两个完整的DataFrame而言,正确的方法不是使用等于运算符(),而是使用.equals 方法。

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

重要提示:.eq 方法相当于 ,而不是 .equals 方法。

print(f'输出结果 \n {df_compare.equals(df_compare)}')

输出结果

True

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

from pandas.testing import assert_frame_equal
print(f'输出结果 \n {assert_frame_equal(df_compare, df_compare) is None}')

输出结果

True

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程