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

Python实现两数据集列相似匹配的方法优化及ID获取咨询

解决方案
  • 核心优化逻辑:提前构建df2的name到对应number的映射字典,用O(1)的字典查找替代pd.merge的O(n log n)排序连接操作,万级规模数据集下速度可提升10~100倍,无需在匹配完成后再做关联操作。

实现代码

步骤1:预处理df2构建映射字典

如果需要保留匹配name对应的所有df2编号,用如下方式构建字典:

import difflib as dl
import numpy as np
import pandas as pd

# 原始数据集
df1 = pd.DataFrame([[1,'one'],[2,'two'],[3,'three'],[4,'four'],[5,'five'],[7,'seven']], columns=['number', 'name'])
df2 = pd.DataFrame([[1,'one'],[2,'two'],[3,'three'],[4,'four'],[5,'five'],[55,'five'],[555,'five'],[6,'six'],[7,'seven'],[77,'seven'],[777,'seven'],[8,'eight']], columns=['number', 'name'])

# 构建name到所有对应number的映射字典,仅需遍历一次df2
df2_name_to_nums = df2.groupby('name')['number'].agg(list).to_dict()

如果你的去重逻辑是保留每个匹配name的最后一个df2编号,可直接构建更高效的单值映射字典:

# 仅保留每个name对应的最后一个number,和现有去重keep="last"逻辑完全对齐
df2_name_last_num = df2.drop_duplicates(subset=['name'], keep='last').set_index('name')['number'].to_dict()

步骤2:改造apply逻辑直接返回匹配结果+对应df2编号

以单值映射字典为例,代码如下:

def get_matches_with_id(name):
    # 先获取相似匹配的name
    matched_names = dl.get_close_matches(name, df2['name'], cutoff=0.75, n=5)
    # 直接返回包含匹配name和对应df2编号的元组列表
    return [(matched_name, df2_name_last_num[matched_name]) for matched_name in matched_names]

df1['match_result'] = df1['name'].apply(get_matches_with_id)

步骤3:展开结果完成去重

# 展开列表匹配结果
df1 = df1.explode('match_result').reset_index(drop=True)
# 拆分匹配结果为两列
df1[['duplicates', 'df2_number']] = pd.DataFrame(df1['match_result'].tolist(), index=df1.index)
# 去重、清理冗余列
df1 = df1.drop_duplicates(subset=['duplicates'], keep='last').drop(columns=['match_result']).reset_index(drop=True)

最终输出示例

numbernameduplicatesdf2_number
1oneone1
2twotwo2
3threethree3
4fourfour4
5fivefive555
7sevenseven777

进阶优化

如果数据规模超过10万条,可将difflib替换为fuzzywuzzy[speedup]库,底层为C实现的相似匹配算法,匹配速度可再提升数倍。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:06:03