如何高效实现Pandas中DataFrame单列与多列匹配并填充ID?
高效匹配DataFrame并填充ID的解决方案
问题背景
现有两个DataFrame:
df1:
import pandas as pd df1 = pd.DataFrame({ 'ID': ['', '', ''], 'name1': ['company-1', 'company2', 'company 3'] })
df2:
df2 = pd.DataFrame({ 'ID': ['1', '2'], 'name2': ['company1', 'company2'], 'name3': ['company.1', 'company.2'], 'name4': ['company-1', 'company-2'] })
需求:将df1['name1']与df2中的name2、name3、name4列匹配,匹配成功则将df2对应ID填充到df1的ID列。
当前使用嵌套循环实现,代码如下:
for i in range(len(df1)): for j in range(len(df2)): if df1.iloc[i]['name1'] == df2.iloc[j]['name2']: df1.iloc[i]['ID'] = df2.iloc[j]['ID'] break elif df1.iloc[i]['name1'] == df2.iloc[j]['name3']: df1.iloc[i]['ID'] = df2.iloc[j]['ID'] break elif df1.iloc[i]['name1'] == df2.iloc[j]['name4']: df1.iloc[i]['ID'] = df2.iloc[j]['ID'] break else: df1['ID'][i] = ''
该方法能实现需求,但效率极低(耗时数小时),需要更高效的解决方案。
预期结果:
ID name1 0 '1' 'company-1' 1 '2' 'company2' 2 '' 'company 3'
高效解决方案
利用pandas的melt和merge方法,将df2转换为长格式后进行匹配,时间复杂度远低于嵌套循环:
# 将df2的name2/name3/name4列转成长格式,保留ID melted_df2 = df2.melt(id_vars='ID', value_vars=['name2', 'name3', 'name4'], value_name='matched_name') # 用df1和转换后的df做左连接,匹配name1和matched_name merged_df = df1.merge(melted_df2, left_on='name1', right_on='matched_name', how='left', suffixes=('', '_df2')) # 填充ID列:取匹配到的ID,未匹配到的留空 merged_df['ID'] = merged_df['ID_df2'].fillna('').astype(str) # 保留需要的列 result_df = merged_df[['ID', 'name1']] print(result_df)
代码解释
- melt转换:把df2中分散的name列合并成一列
matched_name,每条记录对应一个名称和对应的ID,将多列匹配转化为单列匹配。 - 左连接merge:以df1为基础,根据
name1和matched_name匹配,保留所有df1的行,匹配成功的记录会带上df2的ID。 - 填充ID:将匹配到的ID填充到原ID列,未匹配的用空字符串填充,最后保留目标列即可。
这种方法利用pandas的向量化操作,避免了逐行循环,数据量越大,效率提升越明显。
首次提问建议
- 提供可直接运行的代码:比如用
pd.DataFrame直接构造示例数据,方便回答者快速复现问题,无需手动整理数据。 - 说明数据规模:比如df1有几万/几十万行,df2的行数,这是判断效率问题的核心依据。
- 明确问题细节:比如当前代码耗时多久、是否需要模糊匹配等特殊规则,帮助回答者给出更精准的方案。
- 列出已尝试的方法:如果试过其他方案(比如apply),可以说明效果,避免重复尝试无效方法。
内容的提问来源于stack exchange,提问作者Victor Odaguiri
相关产品推荐
相关产品推荐

