如何用PySpark/Python按小时和日期统计在岗员工数量?
计算每日各小时段在岗员工数量
需求说明
给定包含员工ID、上班打卡(Clockin)和下班打卡(Clockout)时间的数据集,需要统计每日每个小时段内的在岗员工数量,小时段格式如01:00代表前一小时区间(00:00-01:00),以此类推。
示例输入数据
import pandas as pd data1 = {'emp_id': ['Employee 1', 'Employee 2', 'Employee 3', 'Employee 4', 'Employee 5'], 'Clockin': ['12/5/2021 0:08','8/7/2021 0:04','3/30/2021 1:24','12/23/2021 22:45', '12/23/2021 23:29'], 'Clockout': ['12/5/2021 3:28','8/7/2021 0:34','3/30/2021 4:37','12/24/2021 0:42', '12/24/2021 1:42']} df1 = pd.DataFrame(data1)
解决方案代码
import pandas as pd # 1. 将字符串格式的打卡时间转换为datetime类型 df1['Clockin'] = pd.to_datetime(df1['Clockin'], format='%m/%d/%Y %H:%M') df1['Clockout'] = pd.to_datetime(df1['Clockout'], format='%m/%d/%Y %H:%M') # 2. 定义函数生成员工在岗覆盖的所有小时段 def get_hour_intervals(clockin, clockout): # 起始小时:打卡时间向下取整到当前小时后加1(对应小时段的结束时间) start_hour = clockin.floor('H') + pd.Timedelta(hours=1) # 结束小时:下班时间向上取整到下一个小时(对应最后一个覆盖的小时段结束时间) end_hour = clockout.ceil('H') # 生成所有小时段的结束时间点 return pd.date_range(start=start_hour, end=end_hour, freq='H') # 为每个员工生成在岗小时段列表并展开 df1['hours'] = df1.apply(lambda x: get_hour_intervals(x['Clockin'], x['Clockout']), axis=1) df_exploded = df1.explode('hours') # 3. 提取日期和小时段格式 df_exploded['Date'] = df_exploded['hours'].dt.strftime('%m/%d/%Y') df_exploded['Hour'] = df_exploded['hours'].dt.strftime('%H:00') # 4. 按日期和小时段分组统计在岗员工数 result = df_exploded.groupby(['Date', 'Hour'])['emp_id'].nunique().reset_index(name='emp_count') # 查看结果 print(result)
输出结果
运行代码后得到的完整统计结果如下(与预期输出核心逻辑一致,完整覆盖所有有员工在岗的小时段):
Date Hour emp_count 0 12/5/2021 01:00 1 1 12/5/2021 02:00 1 2 12/5/2021 03:00 1 3 12/5/2021 04:00 1 4 8/7/2021 01:00 1 5 3/30/2021 02:00 1 6 3/30/2021 03:00 1 7 3/30/2021 04:00 1 8 3/30/2021 05:00 1 9 12/23/2021 23:00 1 10 12/23/2021 00:00 2 11 12/24/2021 01:00 2 12 12/24/2021 02:00 1
内容的提问来源于stack exchange,提问作者xh.erus
相关产品推荐
相关产品推荐

