Python中基于两个DataFrame为员工表添加Vacancy列的问题
问题描述
现有两个DataFrame:DF1是员工履历表,DF2是招聘报告表。需要在DF1里新增Vacancy列,满足以下全部条件时标记为Yes,否则为No:
- 员工的
Job字段包含"Manager"(即该员工是经理) - 员工ID出现在DF2的
Hiring_ID中 - 该ID在DF2中对应的
Status不是Open(包括NaN这类非Open状态)
DF1示例数据
ID ManagerID Job Status 1 3 Sales Active 2 3 Sales Active 3 10 Sales Manager Active 4 5 Tech Active 5 12 Tech Manager Active 6 3 Sales Active
DF2示例数据
Hiring_ID Job_Title Status # of Roles 3 Associate Open 8 10 Consultant Open 3 10 Lead Open 1 7 Advisor Open 2 3 Cashier NaN 4
尝试的错误代码
df['Vacant'] = np.where((df['ID'].isin(df2['Hiring_ID'])) & (df2['Status'].isnull()), 'Yes','No')
运行后没得到预期结果(预期ID为3的员工Vacancy值是Yes),需要换个比isin更靠谱的实现方式。
预期结果
ID ManagerID Job Status Vacancy 1 3 Sales Active No 2 3 Sales Active No 3 10 Sales Manager Active Yes 4 5 Tech Active No 5 12 Tech Manager Active No 6 3 Sales Active No
解决方法
问题出在哪?
之前的代码有两个关键错误:
- 漏了判断员工是否是经理的条件
- 直接用
df2['Status'].isnull()会因为DF2和DF1行数不匹配,导致逻辑混乱——应该先从DF2里筛选出符合Status != 'Open'的Hiring_ID,再去匹配DF1的ID
两种可行实现
方案1:先预处理DF2得到有效ID集合,再用np.where判断
先从DF2里挑出所有Status不是Open的Hiring_ID,去重后得到有效ID集合,再结合经理条件一起判断:
import pandas as pd import numpy as np # 从DF2筛选出Status不为Open的Hiring_ID,去重得到有效集合 valid_ids = df2[df2['Status'] != 'Open']['Hiring_ID'].unique() # 给DF1新增Vacancy列 df1['Vacancy'] = np.where( (df1['Job'].str.contains('Manager')) & # 条件1:是经理 (df1['ID'].isin(valid_ids)), # 条件2+3:ID在有效集合里 'Yes', 'No' )
方案2:用merge关联后判断(适合更复杂的关联场景)
如果以后需求变复杂,比如要用到DF2的其他字段,用merge关联更直观:
# 给DF2标记每条记录是否符合Status要求 df2['is_valid'] = df2['Status'] != 'Open' # 按Hiring_ID分组,只要该ID有任意一条符合要求,就标记为有效 valid_hiring = df2.groupby('Hiring_ID')['is_valid'].any().reset_index() # 把DF1和有效ID表关联,缺失值表示ID不在DF2里,标记为无效 df1 = df1.merge(valid_hiring, left_on='ID', right_on='Hiring_ID', how='left') df1['is_valid'] = df1['is_valid'].fillna(False) # 生成Vacancy列 df1['Vacancy'] = np.where( (df1['Job'].str.contains('Manager')) & df1['is_valid'], 'Yes', 'No' ) # 清理临时列(可选) df1 = df1.drop(columns=['Hiring_ID', 'is_valid'])
结果验证
运行上述任意一种方案,DF1都会生成符合预期的Vacancy列:ID为3的员工是经理,且在DF2中有一条Status为NaN的记录,所以标记为Yes,其他员工要么不是经理,要么ID不符合条件,都标记为No。
内容的提问来源于stack exchange,提问作者Coding_Nubie
相关产品推荐
相关产品推荐

