0

0

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

霞舞

霞舞

发布时间:2025-10-25 13:10:01

|

753人浏览过

|

来源于php中文网

原创

使用 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)

输出:

AVCLabs
AVCLabs

AI移除视频背景,100%自动和免费

下载
原始 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 中行对的匹配状态识别和结果标记,为数据质量检查和数据分析提供了实用的工具。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

56

2025.12.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1498

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

623

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

612

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

587

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

170

2025.07.29

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.0万人学习

ASP 教程
ASP 教程

共34课时 | 4.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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