Python Pandas入门:如何统计员工在各Rank及Level的耗时
统计员工在Rank及Level上的实际任职时长
你当前的代码通过count()只能得到对应分组的记录条数,但如果需要基于日期计算实际的任职时长(月份/天数),需要先处理日期列,再通过日期差值来计算。以下分两种常见场景给出实现方案:
场景1:统计每个员工在同一Rank+Level的总任职时长(合并非连续阶段)
适用于不需要区分同一职级的非连续任职,只计算该职级的累计时长。
步骤:
- 将
Month列转换为日期类型,确保可进行时间计算。 - 按
Employee、Rank、Level分组,取每组的最早和最晚日期。 - 基于首尾日期计算总任职月份数或天数。
代码实现:
import pandas as pd # 构造/读取你的数据集 data = { 'Employee': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'], 'Month': ['01-07-2022', '01-09-2022', '01-08-2022', '01-10-2022', '01-12-2022', '01-01-2023', '01-07-2022', '01-09-2022', '01-08-2022', '01-10-2022', '01-12-2022', '01-01-2023'], 'Rank': [10, 10, 10, 10, 10, 11, 7, 7, 9, 9, 11, 12], 'Level': [1, 1, 1, 2, 3, 1, 1, 1, 4, 2, 3, 1] } df = pd.DataFrame(data) # 转换日期格式(匹配你的dd-mm-yyyy格式) df['Month'] = pd.to_datetime(df['Month'], format='%d-%m-%Y') # 分组计算首尾日期及时长 df_tenure = df.groupby(['Employee', 'Rank', 'Level']).agg( start_date=('Month', 'min'), end_date=('Month', 'max') ).reset_index() # 计算任职月份数(包含首尾月) df_tenure['tenure_months'] = (df_tenure['end_date'].dt.year - df_tenure['start_date'].dt.year)*12 + \ (df_tenure['end_date'].dt.month - df_tenure['start_date'].dt.month) + 1 # 计算任职天数(包含首尾日) df_tenure['tenure_days'] = (df_tenure['end_date'] - df_tenure['start_date']).dt.days + 1 print(df_tenure)
输出示例:
Employee Rank Level start_date end_date tenure_months tenure_days 0 A 10 1 2022-07-01 2022-09-01 3 93 1 A 10 2 2022-10-01 2022-10-01 1 31 2 A 10 3 2022-12-01 2022-12-01 1 31 3 A 11 1 2023-01-01 2023-01-01 1 31 4 B 7 1 2022-07-01 2022-09-01 3 93 5 B 9 2 2022-10-01 2022-10-01 1 31 6 B 9 4 2022-08-01 2022-08-01 1 31 7 B 11 3 2022-12-01 2022-12-01 1 31 8 B 12 1 2023-01-01 2023-01-01 1 31
场景2:统计每个员工连续的Rank+Level阶段时长(区分非连续任职)
适用于需要区分同一职级的非连续任职阶段(比如员工中途换了职级,之后又回到原职级),分别计算每个连续阶段的时长。
代码实现:
import pandas as pd # 构造/读取数据集(同场景1) data = { 'Employee': ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'], 'Month': ['01-07-2022', '01-09-2022', '01-08-2022', '01-10-2022', '01-12-2022', '01-01-2023', '01-07-2022', '01-09-2022', '01-08-2022', '01-10-2022', '01-12-2022', '01-01-2023'], 'Rank': [10, 10, 10, 10, 10, 11, 7, 7, 9, 9, 11, 12], 'Level': [1, 1, 1, 2, 3, 1, 1, 1, 4, 2, 3, 1] } df = pd.DataFrame(data) # 转换日期并按员工、日期排序 df['Month'] = pd.to_datetime(df['Month'], format='%d-%m-%Y') df_sorted = df.sort_values(['Employee', 'Month']).reset_index(drop=True) # 标记连续的职级阶段:当Rank/Level变化时,阶段号递增 df_sorted['stage'] = (df_sorted[['Employee', 'Rank', 'Level']] != df_sorted[['Employee', 'Rank', 'Level']].shift()).any(axis=1).cumsum() # 按阶段分组计算时长 stage_tenure = df_sorted.groupby(['Employee', 'stage']).agg( Rank=('Rank', 'first'), Level=('Level', 'first'), start_date=('Month', 'min'), end_date=('Month', 'max') ).reset_index() # 计算时长 stage_tenure['tenure_months'] = (stage_tenure['end_date'].dt.year - stage_tenure['start_date'].dt.year)*12 + \ (stage_tenure['end_date'].dt.month - stage_tenure['start_date'].dt.month) + 1 stage_tenure['tenure_days'] = (stage_tenure['end_date'] - stage_tenure['start_date']).dt.days + 1 # 移除stage列(可选) stage_tenure = stage_tenure.drop('stage', axis=1) print(stage_tenure)
输出示例:
Employee Rank Level start_date end_date tenure_months tenure_days 0 A 10 1 2022-07-01 2022-09-01 3 93 1 A 10 2 2022-10-01 2022-10-01 1 31 2 A 10 3 2022-12-01 2022-12-01 1 31 3 A 11 1 2023-01-01 2023-01-01 1 31 4 B 7 1 2022-07-01 2022-07-01 1 31 5 B 9 4 2022-08-01 2022-08-01 1 31 6 B 7 1 2022-09-01 2022-09-01 1 30 7 B 9 2 2022-10-01 2022-10-01 1 31 8 B 11 3 2022-12-01 2022-12-01 1 31 9 B 12 1 2023-01-01 2023-01-01 1 31
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

