
在数据分析和处理的日常工作中,我们经常需要比较两个结构相似的Pandas DataFrame,以找出它们之间的不同之处。例如,比较不同时间点的数据快照,或验证数据处理前后的变化。理想情况下,我们希望得到的输出不仅能指出哪些行存在差异,还能明确显示这些差异具体发生在哪些列上,并且只保留这些差异化的信息,剔除完全相同的部分。
考虑以下两个DataFrame df1 和 df2:
import pandas as pd
data1 = {
'pet_name': ['Patrick', 'Patrick', 'Patrick', 'Patrick'],
'exam_day': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04'],
'result_1': [1, 2, 3, 4],
'result_2': [10, 20, 30, 40],
'pre_result_1': [123, 123, 123, 123]
}
df1 = pd.DataFrame(data1)
data2 = {
'pet_name': ['Patrick', 'Patrick', 'Patrick', 'Patrick'],
'exam_day': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04'],
'result_1': [1, 99, 3, 4], # Difference here: df1 has 2, df2 has 99
'result_2': [10, 20, 30, 100], # Another difference for demonstration
'pre_result_1': [123, 123, 123, 123]
}
df2 = pd.DataFrame(data2)
print("df1:")
print(df1)
print("\ndf2:")
print(df2)df1:
pet_name exam_day result_1 result_2 pre_result_1 0 Patrick 2023-01-01 1 10 123 1 Patrick 2023-01-02 2 20 123 2 Patrick 2023-01-03 3 30 123 3 Patrick 2023-01-04 4 40 123
df2:
pet_name exam_day result_1 result_2 pre_result_1 0 Patrick 2023-01-01 1 10 123 1 Patrick 2023-01-02 99 20 123 2 Patrick 2023-01-03 3 30 123 3 Patrick 2023-01-04 4 100 123
我们注意到 df1 和 df2 在以下位置存在差异:
如果仅仅使用 merge(..., indicator=True, how="outer") 并过滤 _merge != "both",虽然能识别出有差异的行,但会保留所有列,并且对同一差异行会分别显示 left_only 和 right_only 两条记录,无法直接突出差异所在的具体列。我们的目标是获得一个更精炼的视图,仅包含差异行和差异列,同时保留关键的标识列。
Pandas 1.1.0 版本引入的 DataFrame.compare() 方法是专门为解决这类问题而设计的。它能够进行元素级别的比较,并以一种结构化的方式展示差异。
为了让 compare() 方法能够正确地对齐和比较行,我们需要将DataFrame中的关键标识列(例如 pet_name 和 exam_day)设置为索引。这些列通常被称为“维度”列或“主键”列,它们在比较过程中不应被视为可变的值,而是作为行的唯一标识符。
df1_indexed = df1.set_index(['pet_name', 'exam_day'])
df2_indexed = df2.set_index(['pet_name', 'exam_day'])
print("df1_indexed (partial view):")
print(df1_indexed.head(2))输出示例:
df1_indexed (partial view):
result_1 result_2 pre_result_1
pet_name exam_day
Patrick 2023-01-01 1 10 123
2023-01-02 2 20 123通过设置索引,compare() 方法将基于这些索引值来匹配行。
接下来,我们使用 compare() 方法对两个已设置索引的DataFrame进行比较。关键参数是 align_axis=0,它指示 compare() 在行级别进行对齐。
diff_df_raw = df1_indexed.compare(df2_indexed, align_axis=0)
print("Raw comparison output (diff_df_raw):")
print(diff_df_raw)输出示例:
Raw comparison output (diff_df_raw):
result_1 result_2
pet_name exam_day
Patrick 2023-01-02 self 2.0 NaN
other 99.0 NaN
2023-01-04 self NaN 40.0
other NaN 100.0compare() 方法的输出特点:
为了将 compare() 的输出重塑成我们期望的简洁格式(即每行显示一个差异值,且包含原始的关键标识列),我们需要进行额外的后处理。
以上就是高效识别Pandas DataFrame差异并仅保留差异化数据的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号