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

如何基于首两位标识在DataFrame间匹配含最多共同token的行?

高效匹配同组DataFrame中共同Token最多的行

问题场景

给定两个大型DataFrame(df1、df2),要求对df2的每一行,只在df1中first_two(首两位标识)相同的行里,选出和该行拥有最多共同token的行作为匹配结果;如果对应first_two组在df1中没有行,或者没有共同token,匹配结果设为None。

示例数据

df1

namefirst_two
common workco
summer hotsu
appleap
colorful fallco
support itsu
could compco

df2

namefirst_two
condition work itco
common mistakesco
could comp workco
summersu
appearsap

预期输出

namefirst_twomatch
condition work itcocommon work
common mistakescocommon work
could comp workcocould comp
summersusummer hot
appearsapNone

你已经完成的代码:

df3=(df1.groupby(['first_two'])
      .agg({'name': lambda x: ",".join(x)})
      .reset_index())
merge_=df3.merge(df2, on='first_two',how='inner')

核心待解决问题:如何在merge_的name_x列中,为每个name_y找到含最多共同token的元素?


解决方案

思路

无需把同组name合并成逗号分隔的字符串,先将文本转换为token集合,再按first_two分组计算交集数量,最终选出对应最大值的行即可。

代码实现

1. 预处理:将文本转为Token集合

为两个DataFrame的name列生成对应的token集合,方便快速计算交集:

import pandas as pd

# 给df1添加token集合列
df1['tokens'] = df1['name'].str.split().apply(set)
# 给df2添加token集合列
df2['tokens'] = df2['name'].str.split().apply(set)

2. 基础版匹配逻辑

直接遍历df2每一行,在同组df1中筛选共同token最多的行:

def find_best_match(df2_row, df1_group):
    # 计算当前df2行与同组每个df1行的共同token数量
    common_counts = df1_group['tokens'].apply(lambda x: len(x & df2_row['tokens']))
    max_count = common_counts.max()
    if max_count == 0:
        return None
    # 取第一个达到最大共同token数的df1行name(存在并列时取第一个,可按需调整)
    return df1_group.loc[common_counts.idxmax(), 'name']

# 为df2添加匹配结果列
df2['match'] = df2.apply(
    lambda row: find_best_match(row, df1[df1['first_two'] == row['first_two']]),
    axis=1
)

3. 大型数据集优化版

如果数据量极大,上述apply效率不足,可将df1按first_two分组存入字典,减少重复查询开销:

# 将df1按first_two分组,转换为字典:key为first_two,value为[(tokens集合, name), ...]
grouped_df1 = df1.groupby('first_two')[['tokens', 'name']].apply(list).to_dict()

def fast_match(row):
    group_data = grouped_df1.get(row['first_two'], [])
    if not group_data:
        return None
    max_common = -1
    best_name = None
    target_tokens = row['tokens']
    # 遍历同组所有df1行,筛选共同token最多的条目
    for tokens, name in group_data:
        current_common = len(tokens & target_tokens)
        if current_common > max_common:
            max_common = current_common
            best_name = name
    return best_name if max_common > 0 else None

df2['match'] = df2.apply(fast_match, axis=1)

4. 格式调整(匹配预期输出)

将匹配结果转为代码格式展示:

df2['match'] = df2['match'].apply(lambda x: f"`{x}`" if x is not None else x)

补充说明

  • 若存在多个df1行与当前df2行的共同token数并列最多,上述代码会返回第一个出现的行;如需返回所有匹配行,可修改为收集所有满足common_counts == max_count的name。
  • 针对超大型数据集,建议采用分块处理或Dask框架,避免内存溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:06:27