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

如何用Python简洁实现Pandas按规则筛选每个ID的最新雇佣记录?

解决方案

问题明确

现有包含雇佣历史的Pandas DataFrame(用1900-01-01存储空结束日期),需为每个ID返回一条符合规则的记录:

  • 仅有一个当前雇主 → 返回该记录
  • 无当前雇主 → 返回起始日期最晚的记录
  • 多个当前雇主 → 返回起始日期最早的记录

实现思路

核心是通过标记当前雇佣状态 + 自定义排序优先级,结合分组取首条的方式实现:

  1. 标记每条记录是否为当前雇佣(结束日期等于1900-01-01)
  2. 为记录设置排序键,让符合规则的记录在分组内排到第一位:
    • 当前雇佣记录优先排在前面
    • 当前雇佣组内按起始日期升序(取最早的)
    • 非当前雇佣组内按起始日期降序(取最晚的)
  3. 按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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:10:17