如何用Python简洁实现Pandas按规则筛选每个ID的最新雇佣记录?
解决方案
问题明确
现有包含雇佣历史的Pandas DataFrame(用1900-01-01存储空结束日期),需为每个ID返回一条符合规则的记录:
- 仅有一个当前雇主 → 返回该记录
- 无当前雇主 → 返回起始日期最晚的记录
- 多个当前雇主 → 返回起始日期最早的记录
实现思路
核心是通过标记当前雇佣状态 + 自定义排序优先级,结合分组取首条的方式实现:
- 标记每条记录是否为当前雇佣(结束日期等于
1900-01-01) - 为记录设置排序键,让符合规则的记录在分组内排到第一位:
- 当前雇佣记录优先排在前面
- 当前雇佣组内按起始日期升序(取最早的)
- 非当前雇佣组内按起始日期降序(取最晚的)
- 按ID分组后取每组第一条即可
代码实现
import pandas as pd import numpy as np # 示例数据构造(可替换为你的实际数据) data = { 'ID': [1,1,1,2,2,3,3,3], 'employer': ['A','B','C','D','E','F','G','H'], 'start_date': ['2020-01-01','2021-01-01','1900-01-01','2019-01-01','2022-01-01','2018-01-01','2020-01-01','2023-01-01'], 'end_date': ['1900-01-01','1900-01-01','2022-01-01','2021-01-01','2023-01-01','2021-01-01','2022-01-01','2024-01-01'] } df = pd.DataFrame(data) # 转换为日期格式 df['start_date'] = pd.to_datetime(df['start_date']) df['end_date'] = pd.to_datetime(df['end_date']) # 1. 标记当前雇佣状态 df['is_current'] = df['end_date'] == pd.to_datetime('1900-01-01') # 2. 构造排序键:当前雇佣用原起始日期(升序取最早),非当前用负时间戳(升序等价于原日期降序) df['sort_key'] = np.where( df['is_current'], df['start_date'], -df['start_date'].astype('int64') # 转时间戳取负实现降序 ) # 3. 排序+分组取首条 result = df.sort_values( by=['ID', 'is_current', 'sort_key'], ascending=[True, False, True] ).groupby('ID').head(1).drop(['is_current', 'sort_key'], axis=1) print(result)
代码说明
is_current列:快速区分当前/非当前雇佣记录,确保当前记录优先被保留sort_key列:巧妙利用数值排序逻辑,在同一分组内同时满足两种排序需求(当前取最早,非当前取最晚)- 全局排序后分组取
head(1),比分组内单独排序效率更高,适合大数据集
内容的提问来源于stack exchange,提问作者grarons
相关产品推荐
相关产品推荐

