如何为员工DataFrame按ID和合同类型生成按日期排序的Order列
给员工合同按分组生成日期逆序序号
需求
给定包含员工合同信息的DataFrame,需按ID+Contract分组,新增Order列:
- 按合同日期从新到旧排序,最新的合同标记为1
- 日期相同时,序号顺序无要求(按记录出现顺序分配即可)
原始数据
ID Name Contract Date 10000 John Employee 2021-01-01 10000 John Employee 2021-01-01 10000 John Employee 2020-03-06 10000 John Contractor 2021-01-03 10000 John Agency 2021-01-01 10000 John Contractor 2021-02-01 10001 Carmen Employee 1988-06-03 10001 Carmen Employee 2021-02-03 10001 Carmen Contractor 2021-02-03 10002 Peter Contractor 2021-02-03 10003 Fred Employee 2020-01-05 10003 Fred Employee 1988-06-03
预期输出
ID Name Contract Date Order 10000 John Employee 2021-01-01 1 10000 John Employee 2021-01-01 2 10000 John Employee 2020-03-06 3 10000 John Contractor 2021-01-03 2 10000 John Agency 2021-01-01 1 10000 John Contractor 2021-02-01 1 10001 Carmen Employee 1988-06-03 1 10001 Carmen Employee 2021-02-03 2 10001 Carmen Contractor 2021-02-03 1 10002 Peter Contractor 2021-02-03 1 10003 Fred Employee 2020-01-05 2 10003 Fred Employee 1988-06-03 1
实现代码(Pandas)
import pandas as pd # 构造原始DataFrame(如果数据来自文件,替换为pd.read_csv/pd.read_excel等即可) data = [ [10000, 'John', 'Employee', '2021-01-01'], [10000, 'John', 'Employee', '2021-01-01'], [10000, 'John', 'Employee', '2020-03-06'], [10000, 'John', 'Contractor', '2021-01-03'], [10000, 'John', 'Agency', '2021-01-01'], [10000, 'John', 'Contractor', '2021-02-01'], [10001, 'Carmen', 'Employee', '1988-06-03'], [10001, 'Carmen', 'Employee', '2021-02-03'], [10001, 'Carmen', 'Contractor', '2021-02-03'], [10002, 'Peter', 'Contractor', '2021-02-03'], [10003, 'Fred', 'Employee', '2020-01-05'], [10003, 'Fred', 'Employee', '1988-06-03'] ] df = pd.DataFrame(data, columns=['ID', 'Name', 'Contract', 'Date']) # 将Date列转为datetime类型,确保日期排序逻辑正确 df['Date'] = pd.to_datetime(df['Date']) # 按ID和Contract分组,对日期降序生成序号,同日期按原顺序分配 df['Order'] = df.groupby(['ID', 'Contract'])['Date'].rank(ascending=False, method='first').astype(int) # 输出无索引的结果 print(df.to_string(index=False))
关键逻辑说明
- 日期类型转换:必须将
Date从字符串转为datetime类型,避免非标准日期格式导致的排序错误。 - 分组rank:
groupby(['ID', 'Contract']):限定只在同一员工的同类型合同内进行排序。ascending=False:让最新的日期对应序号1,符合预期输出的排序逻辑。method='first':同日期的记录按原始出现顺序分配不同序号,避免序号重复。astype(int):将rank生成的浮点数转为整数,匹配预期输出的格式。
内容的提问来源于stack exchange,提问作者Paulo Cortez
相关产品推荐
相关产品推荐

