使用 Pandas 确定 DataFrame 中行对的匹配状态并标记通过/失败

霞舞
发布: 2025-10-25 13:10:01
原创
717人浏览过

使用 pandas 确定 dataframe 中行对的匹配状态并标记通过/失败

本文详细介绍了如何使用 Pandas 库高效地识别 DataFrame 中“Source”和“Target”行对的匹配状态。通过将数据拆分为源和目标子集,并利用 `pd.merge` 的内连接操作,可以精确地确定匹配的行对。随后,文章将指导如何将“Pass”或“Fail”状态标记到原始 DataFrame 的“Source”行中,并调整列顺序以满足特定的输出要求。

在数据处理和分析中,经常需要比较数据集中的相关记录,并根据预设条件判断它们是否匹配。本教程将展示如何利用 Pandas DataFrame 的强大功能,识别成对出现的“Source”和“Target”行之间的匹配关系,并为“Source”行添加一个“Result”列,标记为“Pass”或“Fail”。

1. 问题描述与数据准备

我们的目标是处理一个包含“Source”和“Target”类型行的 DataFrame。对于每对 Source/Target,我们需要比较它们在指定列(例如 Col1, Col2, Col3)上的值。如果 Source 行的所有指定列都与相应的 Target 行匹配,则该 Source 行的结果为“Pass”;否则为“Fail”。Target 行的“Result”列应留空。

首先,我们创建示例 DataFrame:

import pandas as pd

data = {
    'Obs': [1, 2, 3, 4, 5, 6],
    'Dataset': ['Source', 'Target', 'Source', 'Target', 'Source', 'Target'],
    'Col1': ['A', 'A', 'B', 'B', 'C', 'D'],
    'Col2': [10, 10, 20, 20, 30, 30],
    'Col3': ['X', 'X', 'Y', 'Y', 'Z', 'Z']
}
df = pd.DataFrame(data)
print("原始 DataFrame:")
print(df)
登录后复制

输出:

标书对比王
标书对比王

标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。

标书对比王58
查看详情 标书对比王
原始 DataFrame:
   Obs Dataset Col1  Col2 Col3
0    1  Source    A    10    X
1    2  Target    A    10    X
2    3  Source    B    20    Y
3    4  Target    B    20    Y
4    5  Source    C    30    Z
5    6  Target    D    30    Z
登录后复制

2. 核心匹配逻辑:识别“Pass”对

识别“Pass”对的关键在于找到在所有比较列上都完全相同的 Source 和 Target 行。Pandas 的 merge 函数是实现这一目标的理想工具。我们将利用 inner 连接,它只保留在两个 DataFrame 中都存在且在指定键列上匹配的行。

  1. 分离 Source 和 Target 数据: 为了进行比较,首先将原始 DataFrame 拆分为两个独立的 DataFrame:一个只包含“Source”行,另一个只包含“Target”行。保留原始的 Obs 列对于后续将结果映射回原始 DataFrame 至关重要。

    source_df = df[df['Dataset'] == 'Source'].copy()
    target_df = df[df['Dataset'] == 'Target'].copy()
    登录后复制
  2. 执行内连接以识别匹配项: 使用 pd.merge 对 source_df 和 target_df 进行内连接。连接键是用于比较的列 (Col1, Col2, Col3)。这将返回一个 DataFrame,其中只包含那些在 Col1, Col2, Col3 上与 target_df 中某行完全匹配的 source_df 行。

    # 定义用于匹配的列
    matching_cols = ['Col1', 'Col2', 'Col3']
    
    # 识别出在Source和Target中都存在的匹配对
    # pass_identifiers 将包含那些成功匹配的Source行的Obs值及匹配列值
    pass_identifiers = pd.merge(
        source_df[['Obs'] + matching_cols],
        target_df[matching_cols],
        on=matching_cols,
        how='inner'
    )
    print("\n匹配成功的 Source 行标识符:")
    print(pass_identifiers)
    登录后复制

输出:

匹配成功的 Source 行标识符:
   Obs Col1  Col2 Col3
0    1    A    10    X
1    3    B    20    Y
登录后复制

pass_identifiers DataFrame 告诉我们,原始 DataFrame 中 Obs 为 1 和 3 的 Source 行是匹配成功的。

3. 应用结果并分配状态

现在我们已经识别出哪些 Source 行应该被标记为“Pass”,接下来就是将这些结果应用到原始 DataFrame 中,并处理“Fail”情况以及列的重新排序。

  1. 初始化“Result”列: 在原始 DataFrame 中添加一个名为 Result 的新列,并将其所有值初始化为空字符串。

    df['Result'] = ''
    登录后复制
  2. 标记“Pass”行: 根据 pass_identifiers 中的 Obs 值,更新原始 DataFrame 中相应 Source 行的 Result 列为“Pass”。

    # 找出原始df中属于Source且其Obs值在pass_identifiers中的行
    df.loc[(df['Dataset'] == 'Source') & (df['Obs'].isin(pass_identifiers['Obs'])), 'Result'] = 'Pass'
    登录后复制
  3. 标记“Fail”行: 对于那些是 Source 行但未被标记为“Pass”的行,将其 Result 列设置为“Fail”。

    # 找出原始df中属于Source但Result列仍为空的行(即未匹配成功的Source行)
    df.loc[(df['Dataset'] == 'Source') & (df['Result'] == ''), 'Result'] = 'Fail'
    登录后复制
  4. 重新排序列: 根据期望的输出格式,将 Result 列移动到 Dataset 列之后。

    # 重新组织列的顺序
    df = df[['Obs', 'Dataset', 'Result', 'Col1', 'Col2', 'Col3']]
    登录后复制

4. 完整代码示例

将上述所有步骤整合,即可得到最终的处理逻辑:

import pandas as pd

# 1. 原始数据准备
data = {
    'Obs': [1, 2, 3, 4, 5, 6],
    'Dataset': ['Source', 'Target', 'Source', 'Target', 'Source', 'Target'],
    'Col1': ['A', 'A', 'B', 'B', 'C', 'D'],
    'Col2': [10, 10, 20, 20, 30, 30],
    'Col3': ['X', 'X', 'Y', 'Y', 'Z', 'Z']
}
df = pd.DataFrame(data)

print("--- 原始 DataFrame ---")
print(df)

# 定义用于匹配的列
matching_cols = ['Col1', 'Col2', 'Col3']

# 2. 分离 Source 和 Target 数据
source_df = df[df['Dataset'] == 'Source'].copy()
target_df = df[df['Dataset'] == 'Target'].copy()

# 3. 识别“Pass”对
# 使用内连接找到在所有匹配列上都一致的 Source 行的 Obs
pass_identifiers = pd.merge(
    source_df[['Obs'] + matching_cols],
    target_df[matching_cols],
    on=matching_cols,
    how='inner'
)

# 4. 初始化“Result”列
df['Result'] = ''

# 5. 标记“Pass”行
# 筛选出原始df中属于Source且其Obs值在pass_identifiers中的行,标记为'Pass'
df.loc[(df['Dataset'] == 'Source') & (df['Obs'].isin(pass_identifiers['Obs'])), 'Result'] = 'Pass'

# 6. 标记“Fail”行
# 筛选出原始df中属于Source但Result列仍为空的行,标记为'Fail'
df.loc[(df['Dataset'] == 'Source') & (df['Result'] == ''), 'Result'] = 'Fail'

# 7. 重新排序列
df = df[['Obs', 'Dataset', 'Result', 'Col1', 'Col2', 'Col3']]

print("\n--- 处理后的 DataFrame ---")
print(df)
登录后复制

最终输出:

--- 原始 DataFrame ---
   Obs Dataset Col1  Col2 Col3
0    1  Source    A    10    X
1    2  Target    A    10    X
2    3  Source    B    20    Y
3    4  Target    B    20    Y
4    5  Source    C    30    Z
5    6  Target    D    30    Z

--- 处理后的 DataFrame ---
   Obs Dataset Result Col1  Col2 Col3
0    1  Source   Pass    A    10    X
1    2  Target         A    10    X
2    3  Source   Pass    B    20    Y
3    4  Target         B    20    Y
4    5  Source   Fail    C    30    Z
5    6  Target         D    30    Z
登录后复制

这正是我们期望的输出结果,其中 Source 行根据匹配情况被正确标记为“Pass”或“Fail”,而 Target 行的 Result 列保持为空。

5. 注意事项与总结

  • “Fail”的定义: 在本教程中,“Fail”特指 Source 行在指定的匹配列上未能找到对应的 Target 行。如果存在 Target 行没有匹配的 Source 行,它们不会影响 Source 行的“Pass”或“Fail”状态,且其 Result 列将保持为空。如果需要识别这些孤立的 Target 行,可以使用 pd.merge 的 how='left' 或 how='right' 操作。
  • 匹配列的灵活性: matching_cols 列表可以根据实际需求包含任意数量的列,这使得该方法非常灵活,适用于不同场景下的数据比较。
  • 性能考量: 对于非常大的 DataFrame,pd.merge 是一个经过优化的操作,通常比迭代行效率更高。然而,如果数据量极其庞大,仍需关注内存使用情况。
  • 数据结构假设: 本方法假设 Source 和 Target 行是通过 Col1, Col2, Col3 等业务键进行逻辑配对的,而不是严格依赖于它们的物理顺序(如 Obs 值的连续性)。这种基于值匹配的方法更加健壮。

通过上述步骤,我们成功地利用 Pandas 实现了 DataFrame 中行对的匹配状态识别和结果标记,为数据质量检查和数据分析提供了实用的工具。

以上就是使用 Pandas 确定 DataFrame 中行对的匹配状态并标记通过/失败的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号