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

Pandas合并DataFrame后二次匹配填充NaN缺失值的实现方法

多规则分层合并补全缺失值方案

核心逻辑:放弃依赖索引的combine_first方案,采用分层匹配策略——优先用精度更高的「First Name + 邮箱」规则做第一轮匹配,再针对第一轮未匹配到的行,用「First Name + Last Name」规则做第二轮匹配补全,最后拼接结果,从根源避免行错配、重复问题。


1. 导入依赖并加载原始数据

import pandas as pd
import numpy as np

df1 = pd.DataFrame([['Elle', 'Kelly', 'ellemoore@email.com', 2],
['Amanda','Johnson', 'johnson.amanda@email.com', 5], 
['Jay', 'Rogers', 'jay.rogers@email.com', 4], 
['David','Connor', 'famconnor@email.com', 3],
['Rachel','Connor','famconnor@email.com', 2],
['Anne','Smith','anniesmith@email.com', 4],
['Anne','Smith', 'asmith@email.com', 2],
['Dani', 'Carter', 'daniellecarter@email.com', 3],
['Drake', 'Walker', 'dwalker@email.com', 2]], 
columns = ['First Name', 'Last Name', 'Email', 'Rating'])

df2 = pd.DataFrame([[np.nan, np.nan, np.nan, 1040, 'City'], 
['Dani','Carter-Hampton', 'daniellecarter@email.com', 1040, 'New York'],
['Anne','Smith','anniesmith@email.com', 1040, 'New York'], 
['David', 'Connor', 'famconnor@email.com', 1040, 'Chicago'], 
['Jay', 'Rogers','jrogers@email.com', 1040, 'Los Angeles'], 
['Anne','Smith', 'asmith@email.com', 1040, 'Houston'],
['Amanda','Johnson','johnson.amanda@email.com', 1040, 'Los Angeles'],
['Rachel', 'Connor', 'famconnor@email.com', 1040, 'Chicago'],
['Elle', 'Moore-Kelly', 'moorekellyentertainment@email.com', 1040, 'Los Angeles'],
['Drake', 'Walker', 'walkerproductions@email.com', 1040, 'Los Angeles']],
columns = ['First Name','Last Name','Contact Email','Movie Id','Location'])

2. 第一轮高精度匹配(First Name + 邮箱)

优先用唯一度更高的邮箱字段匹配,保证匹配准确率:

merged_first = df1.merge(
    df2, 
    left_on = ['First Name', 'Email'], 
    right_on =  ['First Name', 'Contact Email'], 
    how = 'right'
)

3. 拆分已匹配/未匹配数据,做第二轮姓名维度匹配

第一轮匹配成功的行特征是Rating字段非空(该字段只来自df1),拆分后仅对未匹配部分做第二轮匹配,避免重复计算:

# 拆分数据集
matched_part = merged_first[merged_first['Rating'].notna()].copy()
unmatched_part = merged_first[merged_first['Rating'].isna()].copy()

# 清理未匹配部分的冗余列,保留df2原始字段
unmatched_part = unmatched_part[df2.columns.tolist()]

# 第二轮按First Name + Last Name匹配,仅取需要的Rating字段
merged_second = unmatched_part.merge(
    df1[['First Name', 'Last Name', 'Rating']],
    on = ['First Name', 'Last Name'],
    how = 'left'
)

4. 拼接结果并整理格式

# 纵向拼接两部分结果
final_result = pd.concat([matched_part, merged_second], ignore_index=True)

# 调整列顺序,对齐期望输出
final_result = final_result[['First Name', 'Last Name', 'Email', 'Rating', 'Contact Email', 'Movie Id', 'Location']]

注意事项:如果业务数据中存在大量同名同姓的重复记录,可以在第二轮合并前对df1做去重处理(比如按时间取最新记录、按Rating取最高记录),避免合并后出现行数膨胀。本次样例数据中重名的Anne Smith已经在第一轮通过邮箱完成精准匹配,第二轮不会出现重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:46:01