You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何比较两个DataFrame的groupby结果值并找出数据集交集?

解决两个姓名DataFrame的交集匹配问题

嘿,我来帮你搞定这个姓名匹配的问题!你的思路完全没问题——按姓氏分组后再做名字匹配确实是高效的方式,下面一步步给你拆解实现方案:

步骤1:拆分姓名为姓氏和名字

首先把两个DataFrame里的姓名按「逗号+空格」拆分,提取出姓氏和独立的名字部分:

import pandas as pd

# 初始化你的示例数据
t1 = pd.DataFrame(['Abe, John Doe', 'Smith, Brian', 'Lin, Sam', 'Lin, Greg'], columns=['t1'])
t2 = pd.DataFrame(['Abe, John', 'Smith, Brian', 'Lin, Sam', 'Lu, John'], columns=['t2'])

# 拆分t1的姓名列,生成姓氏和名字列
t1[['last_name', 'first_name']] = t1['t1'].str.split(', ', expand=True)
# 对t2做同样的拆分操作
t2[['last_name', 'first_name']] = t2['t2'].str.split(', ', expand=True)

步骤2:按姓氏分组,整理名字集合

为了快速做匹配检查,我们把每个姓氏对应的所有名字整理成集合(集合的成员检查速度远快于列表):

# t1按姓氏分组,把同姓氏的名字聚合为集合
t1_groups = t1.groupby('last_name')['first_name'].agg(set).reset_index()
# t2做同样的分组聚合
t2_groups = t2.groupby('last_name')['first_name'].agg(set).reset_index()

现在两个分组结果的结构是:每行对应一个姓氏,以及该姓氏下的所有名字集合,方便后续对比。

步骤3:找出符合条件的交集

接下来我们把两个分组结果按姓氏合并,然后检查t2的名字是否能在t1对应姓氏的名字集合中找到匹配(比如t2的"John"是否包含在t1的"John Doe"里):

# 按姓氏合并两个分组DataFrame
merged = pd.merge(t1_groups, t2_groups, on='last_name', suffixes=('_t1', '_t2'))

# 定义匹配函数:检查t2的名字是否是t1中某个名字的子串
def check_name_match(names_t1, names_t2):
    matched = []
    for name_t2 in names_t2:
        # 判断t2的名字是否出现在t1的任意一个名字中
        if any(name_t2 in name_t1 for name_t1 in names_t1):
            matched.append(name_t2)
    return matched if matched else None

# 应用函数,找出每个姓氏下的匹配名字
merged['matched_names'] = merged.apply(lambda row: check_name_match(row['first_name_t1'], row['first_name_t2']), axis=1)

# 过滤出有匹配结果的行,还原成原始姓名格式
result = merged.dropna(subset=['matched_names']).explode('matched_names')
result['full_name'] = result['last_name'] + ', ' + result['matched_names']

# 输出最终交集结果
print(result[['full_name']])

运行后会得到你要的交集:

full_name
0       Abe, John
1    Smith, Brian
2       Lin, Sam

关于对比两个DataFrame的groupby结果

如果你需要直接操作两个groupby对象的值,有两种常用方法:

  • 转成字典对比:把groupby结果转成「姓氏: 名字集合」的字典,直接按键访问对比,适合快速遍历:
    t1_name_dict = t1.groupby('last_name')['first_name'].agg(set).to_dict()
    t2_name_dict = t2.groupby('last_name')['first_name'].agg(set).to_dict()
    
    # 遍历t2的姓氏,检查是否在t1中存在匹配
    for last_name, t2_names in t2_name_dict.items():
        if last_name in t1_name_dict:
            t1_names = t1_name_dict[last_name]
            # 这里可以自定义对比逻辑,比如求完全交集、部分包含等
            common = [name for name in t2_names if any(name in t1_name for t1_name in t1_names)]
            if common:
                print(f"姓氏 {last_name} 的匹配名字:{common}")
    
  • 合并后逐行处理:就像前面步骤3那样,用pd.merge合并分组结果后,通过apply逐行处理每组数据,这种方式能保留DataFrame结构,方便后续的数据分析和导出。

内容的提问来源于stack exchange,提问作者psak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:28:46