基于另一个DataFrame的条件更新df2的status列
基于df1更新df2的status列解决方案
原始数据
df1
|email_id | date |role |abc@gmail.com | '2022-09-08' |1 |abc@gmail.com | '2022-07-01' |1 |abc@gmail.com | nan |1 |xyz@gmail.com | '2022-04-01' |1 |gmh@gmail.com | nan |1 |ytr@gmail.com | '2022-09-08' |1 |ytr@gmail.com | '2022-09-02' |1
df2
|email_id | status |role |abc@gmail.com | 1 |1 |xyz@gmail.com | 0 |2 |gmh@gmail.com | 1 |1 |ytr@gmail.com | 1 |2
需求规则
更新df2的status列:
- 若df1中对应
email_id的所有date值均非空,status设为0 - 若df1中对应
email_id存在至少一个date为空值,status设为1
预期输出
|email_id | status |role |abc@gmail.com | 1 |1 |xyz@gmail.com | 0 |2 |gmh@gmail.com | 1 |1 |ytr@gmail.com | 0 |2
已尝试代码
df1 = df1.sort_values(by=["email_id","date"]) df1 = (df1[["email_id","date"]]).reset_index()
解决方案
可以通过分组判断+映射更新的方式完成需求,以下是两种可行实现:
方法1:分组生成映射表后合并更新
# 1. 对df1按email_id分组,判断每组是否存在date空值,生成status映射表 status_map = df1.groupby('email_id')['date'].apply(lambda x: 1 if x.isna().any() else 0).reset_index(name='status') # 2. 合并映射表到df2,替换原status列 df2 = df2.merge(status_map, on='email_id', how='left') df2 = df2.drop('status_x', axis=1).rename(columns={'status_y': 'status'})
方法2:用map方法直接替换(更简洁)
# 生成email_id到status的映射字典 status_dict = df1.groupby('email_id')['date'].apply(lambda x: 1 if x.isna().any() else 0).to_dict() # 直接映射更新df2的status列 df2['status'] = df2['email_id'].map(status_dict)
逻辑说明
x.isna().any():检查当前分组的date列是否存在空值,返回布尔值- 分组后通过lambda将布尔值转换为1/0的状态值,得到每个
email_id对应的目标status - 用
merge或map将状态值匹配到df2的对应行,完成更新
内容的提问来源于stack exchange,提问作者deepu2711
相关产品推荐
相关产品推荐

