如何匹配两个DataFrame的email_id并更新df2的status值
基于DataFrame邮箱匹配更新状态字段
问题背景
现有两个DataFrame:
df1结构
|email_id| date | |abc@gmail.com | ['2022-04-09'] | |ABC@gmail.com | [nan] |def@gmail.com | ['2022-09-21','2022-03-09'] | |ghi@gmail.com | [nan, '2022-03-29'] | |jkl@gmail.com | [nan] | |mnp@gmail.com | [nan,'2022-09-01']
df2结构
|email_id| status | |abc@gmail.com | 0 | |def@gmail.com | 0 | |ghi@gmail.com | 0 | |mno@gmail.com | 3 | |pqr@gmail.com | 2 | |MNP@gmail.com | 1 |
需求
将df2的email_id与df1匹配,更新status字段:
- 匹配到的邮箱:若df1对应
date列包含nan,status设为1;若date列无nan,status设为0 - 未在df1中匹配到的邮箱,保持原status不变
解决方案
步骤1:预处理df1,生成匹配映射
先统一邮箱大小写(避免大小写导致的匹配失败),同时标记每个邮箱的date列表是否包含nan,最终生成邮箱到目标status的映射字典。
步骤2:更新df2的status字段
利用映射字典匹配df2的邮箱,未匹配项保留原status值。
完整代码
import pandas as pd import numpy as np # 创建示例DataFrame(若已有数据可跳过此部分) df1 = pd.DataFrame({ 'email_id': ['abc@gmail.com', 'ABC@gmail.com', 'def@gmail.com', 'ghi@gmail.com', 'jkl@gmail.com', 'mnp@gmail.com'], 'date': [['2022-04-09'], [np.nan], ['2022-09-21','2022-03-09'], [np.nan, '2022-03-29'], [np.nan], [np.nan,'2022-09-01']] }) df2 = pd.DataFrame({ 'email_id': ['abc@gmail.com', 'def@gmail.com', 'ghi@gmail.com', 'mno@gmail.com', 'pqr@gmail.com', 'MNP@gmail.com'], 'status': [0, 0, 0, 3, 2, 1] }) # 预处理df1:统一邮箱小写,标记是否含nan df1['email_lower'] = df1['email_id'].str.lower() df1['has_nan'] = df1['date'].apply(lambda x: any(pd.isna(val) for val in x)) # 生成邮箱到目标status的映射 status_map = df1.set_index('email_lower')['has_nan'].map({True: 1, False: 0}).to_dict() # 更新df2的status字段 df2['status'] = df2['email_id'].str.lower().map(status_map).fillna(df2['status']).astype(int) # 查看结果 print(df2)
输出结果
email_id status 0 abc@gmail.com 1 1 def@gmail.com 0 2 ghi@gmail.com 1 3 mno@gmail.com 3 4 pqr@gmail.com 2 5 MNP@gmail.com 1
关键说明
- 大小写统一:将邮箱转为小写,确保
abc@gmail.com和ABC@gmail.com这类大小写不同的同一邮箱能正确匹配 - nan判断:通过
apply遍历每个date列表,用pd.isna检查是否存在nan值 - 保留原状态:使用
fillna(df2['status'])确保未匹配到的邮箱保留原有status值
内容的提问来源于stack exchange,提问作者deepu2711
相关产品推荐
相关产品推荐

