基于文本精确匹配在Pandas中创建新列并合并DataFrame
问题描述
有如下两个DataFrame:
import pandas as pd proj_df = pd.DataFrame({'reg_id':[1,2,3,4], 'part_no':['P1','P2','P3','P4'], 'partner':['A','B','C','D'], 'cust_name_1': ['ABC PVT LTD','Tesla','Apple','Google'], 'cust_name_2':['ABC','Tesla Ltd','Apple Inc','Google Enterprises'], 'cust_name_3':['ABC','Tesla America','Apple America','Google Ent Pvt ltd']}) data_df = pd.DataFrame({'cust_name': ['ABC','Tesla America','Apple Inc','Google','Google','ABC'], 'partner':['A','B','C','D','E','A'], 'part_no':['P1','P2','P3','P4','P5','P6'], 'qty':[100,100,600,150,320,410]})
需要完成以下操作:
- a) 将proj_df中的客户名列与data_df的cust_name列对比,识别出完全匹配的列;
- b) 从cust_name_1、cust_name_2、cust_name_3中选出与data_df的cust_name列完全匹配的列,若多列完全匹配可任选其一;
- c) 基于part_no和partner列的匹配结果合并两个DataFrame。
尝试过以下代码但未得到预期结果:
unique_names = data_df['cust_name'].tolist() for name in unique_names: proj_df['similarity_ratio'] = proj_df.apply(lambda x: difflib.SequenceMatcher(None, name, x.name_1).ratio(), axis=1)
期望输出为包含reg_id、匹配客户名、part_no、partner、qty等字段的合并结果。
解决方案
步骤1:识别完全匹配的客户名并去重
先把proj_df的三个客户名列转换为长格式,方便和data_df的cust_name做匹配:
# 转换proj_df为长格式,保留核心标识字段 proj_melt = proj_df.melt( id_vars=['reg_id', 'part_no', 'partner'], value_vars=['cust_name_1', 'cust_name_2', 'cust_name_3'], var_name='cust_col', value_name='match_cust_name' ) # 筛选出存在于data_df.cust_name中的记录 proj_matched = proj_melt[proj_melt['match_cust_name'].isin(data_df['cust_name'])] # 每个(reg_id, part_no, partner)组合仅保留一条匹配结果(多列匹配时取第一条) proj_matched_unique = proj_matched.drop_duplicates(subset=['reg_id', 'part_no', 'partner'], keep='first')
步骤2:合并两个DataFrame
基于part_no和partner字段做内连接,提取需要的输出字段:
final_df = pd.merge( proj_matched_unique, data_df, on=['part_no', 'partner'], how='inner' ) # 调整列顺序并保留目标字段 final_df = final_df[['reg_id', 'match_cust_name', 'part_no', 'partner', 'qty']]
最终结果
运行代码后得到的final_df如下:
| reg_id | match_cust_name | part_no | partner | qty |
|---|---|---|---|---|
| 1 | ABC | P1 | A | 100 |
| 1 | ABC | P1 | A | 410 |
| 2 | Tesla America | P2 | B | 100 |
| 3 | Apple Inc | P3 | C | 600 |
| 4 | P4 | D | 150 |
关键说明
- 用
melt转换格式是为了统一遍历所有客户名列,避免逐个列判断的繁琐; drop_duplicates确保每个proj_df条目仅保留一个有效匹配客户名,满足多列匹配任选其一的要求;- 内连接只保留两个表中
part_no和partner都匹配的记录,符合业务需求。
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

