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

如何在Pandas中按条件计算员工岗位及岗责累计时长?

解决员工岗位累计时长计算问题(不计角色)

需求说明

需要结合员工排班数据df_aux和事件数据df_main,计算两个核心指标:

  • 事件发生时,员工在当前岗位的累计时长(不计角色)
  • 事件发生时,员工在当前岗位及角色的累计时长(已实现)

数据示例

先给出原始数据,后续需将时间列转为datetime类型才能进行时间运算:

import pandas as pd

# 排班数据
df_aux = pd.DataFrame({'Worker' : ['Alice','Alice','Alice','Alice','Alice', 'Bob','Bob','Bob'],
                        'Shift_start' : ['2022-01-01 10:00:00', '2022-01-01 10:30:00', '2022-01-01 11:45:00', '2022-01-01 12:45:00', '2022-01-01 13:15:00', '2022-01-01 10:30:00', '2022-01-01 12:00:00', '2022-01-01 13:15:00'],
                        'Shift_end' :   ['2022-01-01 10:15:00', '2022-01-01 11:45:00', '2022-01-01 12:30:00', '2022-01-01 13:15:00', '2022-01-01 14:00:00', '2022-01-01 11:30:00', '2022-01-01 13:10:00', '2022-01-01 14:30:00'],
                        'Position' : [1, 1, 2, 2, 2, 1, 2, 3],
                        'Role' : ['A', 'B', 'B', 'A', 'B', 'A', 'B', 'A']})

# 事件数据
df_main = pd.DataFrame({'Event_time' : ['2022-01-01 11:05:00', '2022-01-01 12:35:00', '2022-01-01 13:25:00'] ,
                        'Position' : [1, 2, 2]})

第一步:数据预处理(转换时间列)

先把所有时间相关列转为datetime类型,这是时间运算的基础:

# 转换排班数据的时间列
df_aux['Shift_start'] = pd.to_datetime(df_aux['Shift_start'])
df_aux['Shift_end'] = pd.to_datetime(df_aux['Shift_end'])

# 转换事件数据的时间列
df_main['Event_time'] = pd.to_datetime(df_main['Event_time'])

第二步:完成已实现的「岗位+角色累计时长」计算

优化原始代码,确保逻辑正确:

# 合并事件与排班数据,按岗位匹配
df_full = df_main.merge(df_aux, on='Position')

# 筛选出事件发生时正在在岗的员工(事件时间在班次起止之间)
df_full = df_full[(df_full['Event_time'] > df_full['Shift_start']) & (df_full['Event_time'] < df_full['Shift_end'])]

# 计算当前岗位+角色的累计时长(当前班次已进行的时间)
df_full['Time_in_position_role'] = df_full['Event_time'] - df_full['Shift_start']

第三步:计算「当前岗位累计时长(不计角色)」

核心思路:对每个在岗员工,统计其在事件时间前所有同岗位班次的总时长,再加上当前班次已进行的时间:

# 定义函数,计算单个员工在指定岗位、指定时间前的累计岗位时长
def calculate_total_position_time(row):
    worker = row['Worker']
    position = row['Position']
    event_time = row['Event_time']
    
    # 筛选该员工所有同岗位的历史班次(班次结束时间 <= 事件时间)
    historical_shifts = df_aux[(df_aux['Worker'] == worker) & 
                               (df_aux['Position'] == position) & 
                               (df_aux['Shift_end'] <= event_time)]
    
    # 计算历史班次的总时长
    total_historical = historical_shifts['Shift_end'].sub(historical_shifts['Shift_start']).sum()
    
    # 加上当前班次已进行的时间,得到累计岗位时长
    return total_historical + row['Time_in_position_role']

# 应用函数计算Time_in_position
df_full['Time_in_position'] = df_full.apply(calculate_total_position_time, axis=1)

最终结果展示

运行上述代码后,df_full会包含两个目标字段:

  • Time_in_position_role:当前岗位+角色的累计时长
  • Time_in_position:当前岗位的累计时长(不计角色)

比如第一个事件(2022-01-01 11:05:00,岗位1)对应的Alice,她的Time_in_position是之前10:00-10:15的15分钟,加上当前10:30到11:05的35分钟,总计50分钟。


内容的提问来源于stack exchange,提问作者datadatadata

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:35:44