Pandas DataFrame差异识别与来源追溯教程

pandas dataframe差异识别与来源追溯教程

本教程详细介绍了如何使用Pandas库高效比较两个DataFrame,识别出它们之间的差异行,并明确这些差异行来源于哪个原始DataFrame。我们将利用pd.merge函数的indicator=True参数来自动生成来源标识,并进一步探讨在合并过程中如何保留并追踪原始DataFrame的行索引,从而实现更精细的数据差异分析。

识别DataFrame差异行及其来源

在数据分析中,经常需要比较两个结构相似但内容可能存在差异的DataFrame,例如比较当前估算与历史估算数据。Pandas提供了强大的合并(merge)功能,结合特定的参数,可以轻松实现这一目标。

核心方法是使用pd.merge函数,并设置how=’outer’和indicator=True。

how=’outer’:执行外连接,这意味着它会保留两个DataFrame中所有不匹配的行,以及匹配的行。indicator=True:这个参数是关键,它会在结果DataFrame中添加一个名为_merge的特殊列。这个列会指示每一行来源于哪个原始DataFrame:left_only:该行仅存在于左侧DataFrame(合并时传入的第一个DataFrame)。right_only:该行仅存在于右侧DataFrame(合并时传入的第二个DataFrame)。both:该行在两个DataFrame中都存在且匹配。

通过筛选_merge列不为’both’的行,我们就能得到所有存在差异的行。

示例代码:识别差异行并标注来源

假设我们有两个DataFrame,df_current_est代表当前估算,df_previous_est代表历史估算。

import pandas as pd# 模拟数据df_current_est = pd.DataFrame({    'EstimateID': [10061, 10062, 10063],    'Season': [2023, 2023, 2023],    'RPIN': ['R1000', 'R2000', 'R3000'],    'GrowMethodCode': ['FO', 'FO', 'FO'],    'Variety_code': ['002', '068', '001'],    'Packout_pc': [0.60, 0.76, 0.80],    'QtyBins': [320, 1000, 500]})df_previous_est = pd.DataFrame({    'EstimateID': [10061, 10062, 10064],    'Season': [2023, 2023, 2023],    'RPIN': ['R1000', 'R2000', 'R4000'],    'GrowMethodCode': ['FO', 'FO', 'FO'],    'Variety_code': ['002', '068', '003'],    'Packout_pc': [0.60, 0.76, 0.90],    'QtyBins': [9000, 90000, 600]})print("df_current_est:")print(df_current_est)print("ndf_previous_est:")print(df_previous_est)# 执行外连接并添加指示器merged_df = pd.merge(df_current_est, df_previous_est, how='outer', indicator=True)# 筛选出存在差异的行(即不完全匹配的行)changed_df = merged_df[merged_df['_merge'] != 'both'].copy()# 打印结果,_merge列清晰地指示了行的来源print("n差异行及其来源:")print(changed_df)

输出解释:在上述示例中,changed_df将包含所有在df_current_est和df_previous_est之间不完全匹配的行。_merge列的值(left_only或right_only)明确告诉我们该差异行是来自当前估算还是历史估算。例如,如果EstimateID为10061的行在df_current_est中QtyBins为320,而在df_previous_est中QtyBins为9000,那么即使其他列相同,由于QtyBins不同,这两行也会被视为差异,并分别显示为left_only和right_only。

注意事项:

不要删除_merge列: _merge列是indicator=True参数生成的关键信息,如果将其删除,就无法直接判断行的来源了。定义“差异”: pd.merge默认是基于所有共享列进行匹配。如果只想基于部分列进行匹配并找出其他列的差异,需要明确指定on参数,并在后续处理中比较非on列。本教程的例子是基于所有列进行匹配。

保留原始DataFrame的行索引

在某些情况下,除了知道差异行来自哪个DataFrame外,我们可能还需要知道这些差异行在原始DataFrame中的具体行索引。_merge列本身不保留原始的行索引信息,因为它生成的是一个新的DataFrame。为了追踪原始索引,我们需要在合并之前将索引转换为普通列。

示例代码:保留原始索引

import pandas as pd# 模拟数据,带有自定义索引df1 = pd.DataFrame({'key': ['one', 'two', 'three'], 'value1': [1, 2, 3]},                   index=[101, 102, 103])df2 = pd.DataFrame({'key': ['two', 'four', 'three'], 'value2': [20, 40, 30]},                   index=[201, 202, 203])print("df1 (带索引):")print(df1)print("ndf2 (带索引):")print(df2)# 在合并前将索引重置为列,并指定后缀以区分merged_df_with_indices = (    pd.merge(df1.reset_index(),  # 将df1的索引转换为'index'列             df2.reset_index(),  # 将df2的索引转换为'index'列             on='key',           # 以'key'列为基准进行合并             suffixes=('_df1', '_df2'), # 为重复列名(包括'index')添加后缀             how='outer',             indicator=True))# 筛选出差异行changed_df_with_indices = merged_df_with_indices.query('_merge != "both"')print("n差异行及其来源和原始索引:")print(changed_df_with_indices)

输出解释:在这个例子中:

df1.reset_index()将df1的索引(101, 102, 103)转换为一个名为index的普通列。df2也进行同样操作。suffixes=(‘_df1’, ‘_df2’)参数在合并时,如果遇到相同名称的非合并键列(如这里的index),会自动添加后缀,生成index_df1和index_df2。最终的changed_df_with_indices不仅包含_merge列指示来源,还包含了index_df1和index_df2列,分别对应差异行在原始df1和df2中的索引。对于left_only的行,index_df2会是NaN;对于right_only的行,index_df1会是NaN。

总结

通过本教程,我们学习了如何利用pd.merge函数的how=’outer’和indicator=True参数来有效地识别Pandas DataFrame之间的差异行,并清晰地追溯每条差异行的原始来源。此外,我们还探讨了通过在合并前重置索引的方法,来保留并追踪差异行在原始DataFrame中的具体行索引,这对于需要回溯数据源的复杂分析场景至关重要。掌握这些技巧,将极大地提升您在处理和比较DataFrame数据时的效率和准确性。

以上就是Pandas DataFrame差异识别与来源追溯教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1369321.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 09:34:13
下一篇 2025年12月14日 09:34:29

相关推荐

  • Python中复杂字典的精确类型描述:Pydantic实践指南

    本文旨在解决Python中对复杂、嵌套字典结构进行精确类型描述的挑战。通过引入Pydantic库,我们展示了如何利用其BaseModel和Python标准类型提示来定义清晰、可验证的数据模型,从而实现对复杂数据结构的强类型支持、数据验证和便捷的数据转换,显著提升代码的可读性和健壮性。 引言:Pyth…

    好文分享 2025年12月14日
    000
  • Pythonic 类间变量传递:利用实例引用共享动态数据

    本文探讨Python中如何在不同类之间高效、优雅地共享动态变化的变量。针对传统方法(如构造函数传递或每次调用时作为参数传递)的局限性,我们提出并演示了一种Pythonic解决方案:通过在构造函数中传递一个类的实例引用,允许接收类直接访问并利用源类中的最新数据,从而实现更简洁、更具封装性的类间协作。 …

    2025年12月14日
    000
  • Python中复杂字典结构的高效类型定义与数据验证:Pydantic实战指南

    本教程旨在解决Python中对复杂、嵌套字典结构进行精确类型定义和数据验证的挑战。通过引入Pydantic库,文章详细演示了如何利用BaseModel创建强类型的数据模型,实现类似Go语言中结构体的精确描述,从而提升代码的健壮性、可读性与开发效率。 引言:Python复杂字典类型定义的困境 在pyt…

    2025年12月14日
    000
  • 使用 GDAL 进行图像重投影:基于控制点的精确校正教程

    本文档旨在指导读者使用 GDAL 库,通过设置控制点的方式对图像进行重投影,实现图像的精确校正。我们将提供详细的代码示例,解释关键步骤,并讨论如何处理常见的图像格式以及如何自定义坐标系统。通过学习本文,你将能够掌握利用控制点进行图像校正的核心技术,并将其应用于实际项目中。 图像重投影原理 图像重投影…

    2025年12月14日
    000
  • Pandas DataFrame中特定值之间填充None值的最佳实践

    本文旨在介绍如何使用Pandas有效地填充DataFrame中两个特定唯一值(例如’A’和’B’)之间的None值,以确保列中没有连续的’A’或’B’。我们将避免使用循环,而是利用Pandas内置函数ff…

    2025年12月14日
    000
  • Pandas DataFrame中填充特定值之间的空值:避免连续的A或B

    本文将深入探讨如何利用 Pandas DataFrame 的强大功能,高效地填充特定值之间的空值。正如摘要所述,我们的目标是在 DataFrame 的某一列中,确保特定值(例如 A 和 B)不会连续出现。我们将避免使用传统的循环方法,而是采用 Pandas 内置函数,如 ffill 和 shift,…

    2025年12月14日
    000
  • dbt模型完整SQL预览:查看包含头部、宏和钩子的最终执行语句

    本文旨在解决dbt用户在模型执行前无法预览完整SQL语句的问题。传统dbt compile仅显示SELECT部分,而dbt run后才能在target/run中查看完整SQL。通过引入dbt show命令,用户现在可以预先查看包含INSERT/MERGE INTO等SQL头部、宏和钩子的最终执行语句…

    2025年12月14日
    000
  • 利用Pandas高效处理DataFrame中值填充以避免连续重复

    本文详细介绍了如何在Pandas DataFrame中高效地填充None值,以确保特定列(如包含’A’和’B’)中不存在连续的相同非空值。通过结合使用ffill()、shift()和布尔索引或mask()方法,可以避免传统循环,实现高性能的矢量化数据处…

    2025年12月14日
    000
  • DBT模型预编译:利用dbt show查看完整生成SQL的实践指南

    dbt compile命令在预编译DBT模型时,无法展示包含INSERT INTO、MERGE INTO等头部语句、宏展开及钩子的完整SQL。本文旨在介绍如何利用dbt show命令,在模型实际运行之前,预览包含所有必要头部信息、宏和钩子的完整生成SQL,从而实现更彻底的SQL审计、调试,并避免运行…

    2025年12月14日
    000
  • 深入解析 DBT:预执行查看完整 SQL 及 DDL/DML 语句

    本文旨在解决 DBT 用户在模型运行前无法查看包含 DDL/DML 头部、宏和钩子在内的完整可执行 SQL 的痛点。通过详细介绍 dbt show 命令,我们将学习如何预先审计和调试 DBT 生成的完整 SQL 语句,尤其是在处理 sql_header 等复杂配置时的应用,从而提升开发效率和代码质量…

    2025年12月14日
    000
  • 从列表中移除指定范围的元素:Python 教程

    本文旨在帮助读者理解并解决从 Python 列表中移除指定数值范围元素的问题。我们将分析原始代码存在的问题,并提供修正后的代码示例,详细解释如何正确地根据起始值和结束值从列表中删除元素,确保最终结果符合预期。本文适合 Python 初学者和有一定基础的开发者阅读。 问题分析 原始代码尝试从用户输入的…

    2025年12月14日
    000
  • Pandas DataFrame 中特定值之间填充 None 值的技巧

    本文介绍了使用 Pandas 库处理 DataFrame 数据时,如何在两个特定的非空值(例如 ‘A’ 和 ‘B’)之间填充 None 值,以避免 DataFrame 列中出现连续的相同非空值。通过 ffill、shift 和布尔索引等 Pandas …

    2025年12月14日
    100
  • 预执行SQL审计:使用dbt show查看完整的DBT生成语句

    dbt compile命令在查看DBT模型生成的SQL时存在局限性,它无法展示完整的DML/DDL头部(如INSERT INTO、MERGE INTO)以及自定义的sql_header配置。本文将详细介绍如何利用dbt show命令,在不实际执行模型的情况下,查看包括SQL头部、宏和钩子在内的完整编…

    2025年12月14日
    000
  • Python列表区间元素移除:避免迭代陷阱与高效切片技巧

    本教程探讨了在Python中从列表中移除指定区间元素时常见的错误,特别是迭代过程中修改列表导致的意外行为。文章将详细解释传统循环移除方法的弊端,并提供一种高效、Pythonic的解决方案,利用列表索引和切片操作精确移除目标范围内的元素,确保代码的正确性和可维护性,同时避免潜在的运行时问题。 理解列表…

    2025年12月14日
    000
  • 从列表中移除指定范围内的元素:Python 教程

    本文旨在解决从Python列表中移除指定数值范围内的元素的问题。我们将提供一个完整的代码示例,该示例允许用户输入一系列数字,并指定一个数值范围。程序随后会从列表中移除该范围内的所有数字,并输出结果列表。本文将详细解释代码的实现原理,并提供优化建议,帮助读者更好地理解和应用该技术。 问题描述 在处理数…

    2025年12月14日
    000
  • Python XML 解析:无需修改 XML 文件提取特定属性

    本文档旨在指导读者如何使用 Python 解析 XML 文件,并在不修改 XML 文件结构的前提下,提取特定的属性值。我们将使用 xml.etree.ElementTree 模块,通过 findall() 方法和 XPath 表达式,精准定位并提取目标属性,例如从具有特定名称的 shape 元素中提…

    2025年12月14日
    000
  • 解决Python中Literal类型赋值引发的Mypy类型检查错误

    在Python中处理Literal类型时,将动态字符串值赋给Literal变量常会引发Mypy类型检查错误,即使经过运行时验证也未能幸免。本文将详细介绍如何使用typing.get_args配合typing.cast或更优雅地利用typing.TypeGuard来解决这些问题,确保代码在类型安全的同…

    2025年12月14日
    000
  • Python XML解析与XPath高级筛选教程

    本教程详细介绍了如何使用Python的xml.etree.ElementTree模块,结合XPath表达式,高效且精准地从复杂XML文件中提取特定数据,而无需修改原始XML结构。内容涵盖XML加载、基础遍历以及利用XPath进行多条件属性筛选的实用技巧与代码示例。 引言 在处理各种数据交换和配置场景…

    2025年12月14日
    000
  • Django 文件上传与处理:获取文件路径的正确实践

    本文详细阐述了在 Django 应用中正确处理文件上传、保存并获取其存储路径的方法。通过分析常见错误,提供优化的代码示例,指导开发者如何安全、高效地接收用户上传的文件,利用 default_storage 进行存储,并将生成的存储路径传递给后续的文件处理函数,确保数据流的准确性和程序的健壮性。 Dj…

    2025年12月14日
    000
  • Django 文件上传与路径管理:确保数据处理的正确路径

    本教程详细阐述了在Django应用中处理文件上传的最佳实践,特别是如何从HTTP请求中正确获取上传文件、将其安全地保存到存储系统,并获取其存储路径。我们将重点讲解request.FILES的使用、default_storage.save()的返回值,以及如何将正确的文件路径传递给后续的文件处理函数,…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信