在Pandas中查找不匹配记录及识别未被唯一值覆盖的记录
在Pandas中查找不匹配记录&验证记录覆盖情况
没问题,我来帮你搞定这个需求!结合你给出的示例代码,我先补全了未写完的第二个数据集,然后分步骤讲解如何实现查找不匹配记录,以及检查某组记录是否被唯一值覆盖:
先准备好完整的示例数据
首先把你给出的代码补全,方便后续演示:
import pandas as pd # 第一个数据集 df_a raw_data = { 'subject_id': ['1', '2', '3', '4', '5'], 'first_name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'], 'last_name': ['Anderson', 'Ackerman', 'Ali', 'Aoni', 'Atiches'], 'sport' : ['soccer','soccer','soccer','soccer','soccer'] } df_a = pd.DataFrame(raw_data, columns = ['subject_id', 'first_name', 'last_name','sport']) # 第二个数据集 df_b(补全你未写完的部分) raw_data_b = { 'subject_id': ['9', '5', '6', '7', '8'], 'first_name': ['Billy', 'Ayoung', 'Brian', 'Bran', 'Bryce'], 'last_name': ['Bonder', 'Atiches', 'Black', 'Balwner', 'Brice'], 'sport' : ['basketball','soccer','basketball','basketball','basketball'] } df_b = pd.DataFrame(raw_data_b, columns = ['subject_id', 'first_name', 'last_name','sport'])
一、查找不匹配的记录
这里分两种场景:一种是完全不在另一个数据集里的记录,另一种是唯一键相同但其他字段不一致的记录。
1. 找出仅在单个数据集中存在的记录
用merge做外连接,加上indicator=True标记每条记录的来源,就能快速筛选出不匹配的条目:
# 基于subject_id做外连接,生成_merge列标记匹配状态 merged_full = df_a.merge(df_b, on='subject_id', how='outer', indicator=True) # 筛选出仅在df_a或仅在df_b中的记录 unmatched_full = merged_full[merged_full['_merge'] != 'both'] print("仅在单个数据集中存在的不匹配记录:") print(unmatched_full)
2. 找出唯一键相同但字段不一致的记录
如果要定位那些subject_id相同,但姓名、运动项目等字段不一样的记录,可以这么做:
# 先筛选出两个数据集共有的subject_id common_subjects = df_a[df_a['subject_id'].isin(df_b['subject_id'])]['subject_id'] # 合并共有记录,给两个数据集的字段加后缀区分 common_merged = df_a.merge(df_b, on='subject_id', suffixes=('_dfa', '_dfb')) # 过滤出字段不一致的记录 field_mismatches = common_merged[ (common_merged['first_name_dfa'] != common_merged['first_name_dfb']) | (common_merged['last_name_dfa'] != common_merged['last_name_dfb']) | (common_merged['sport_dfa'] != common_merged['sport_dfb']) ] print("\n唯一键相同但字段不匹配的记录:") print(field_mismatches)
二、检查记录是否被唯一值覆盖
假设你要验证某组记录的所有唯一键(比如subject_id)是否被另一个数据集的唯一键完全覆盖,可以用isin()结合all()来判断,还能找出具体未被覆盖的记录:
# 检查df_a的所有subject_id是否都在df_b中(即df_b覆盖df_a的唯一键) a_covered_by_b = df_a['subject_id'].isin(df_b['subject_id']).all() print(f"\ndf_a的所有记录是否被df_b的subject_id覆盖:{a_covered_by_b}") # 检查df_b的所有subject_id是否都在df_a中 b_covered_by_a = df_b['subject_id'].isin(df_a['subject_id']).all() print(f"df_b的所有记录是否被df_a的subject_id覆盖:{b_covered_by_a}") # 找出df_a中未被df_b覆盖的具体记录 a_uncovered = df_a[~df_a['subject_id'].isin(df_b['subject_id'])] print("\ndf_a中未被df_b覆盖的记录:") print(a_uncovered)
小技巧:用compare快速对比同索引的字段差异
如果把subject_id设为两个数据集的索引,还可以用compare方法直接生成字段差异对比表:
# 将subject_id设置为索引 df_a_idx = df_a.set_index('subject_id') df_b_idx = df_b.set_index('subject_id') # 对比共同索引的字段差异,keep_shape=True保留所有行 diff_table = df_a_idx.compare(df_b_idx, keep_shape=True) print("\n字段差异对比表:") print(diff_table)
内容的提问来源于stack exchange,提问作者Alejandro Machado
相关产品推荐
相关产品推荐

