0

0

如何按工作日拆分工时并自动分配至最早可用日期

花韻仙語

花韻仙語

发布时间:2026-01-16 12:17:10

|

363人浏览过

|

来源于php中文网

原创

如何按工作日拆分工时并自动分配至最早可用日期

本文介绍一种使用 pandas 高效实现“按 7 小时/天上限、跳过周末、顺序填充工时”的自动化方案,适用于项目排期、资源调度等场景。核心思路是基于业务日偏移动态生成 plannedstart,并智能拆分 hours 字段。

在实际项目管理或人力资源排班中,常需将总工时(如 15 小时)按「单日最多 7 小时」「仅限周一至周五」的约束,从最早起始日开始连续分配。难点在于:工时分配不是独立的——后序 ID 必须避开前序已占满的工作日,即需全局顺序排程,而非简单按 ID 分组处理。

幸运的是,pandas 提供了优雅的向量化解决方案,无需显式循环或状态维护。关键在于利用 BusinessDay 偏移与 groupby.cumcount() 的协同,实现「按需重复行 + 按组递增工作日 + 精确拆分尾数」三步闭环。

✅ 实现步骤详解

首先确保日期列已转为 datetime64 类型(已含在原始代码中):

PicWish
PicWish

推荐!专业的AI抠图修图,支持格式转化

下载
import pandas as pd
import numpy as np

df = pd.DataFrame({
    'ID': [1, 2, 3],
    'EarliestStart': ['28.09.2023', '29.09.2023', '15.11.2023'],
    'Hours': [15.00, 5.00, 23.00]
})
df['EarliestStart'] = pd.to_datetime(df['EarliestStart'], format='%d.%m.%Y')

接着执行核心逻辑:

# Step 1: 按所需天数重复每行(向上取整:ceil(Hours / 7))
out = df.loc[df.index.repeat(np.ceil(df['Hours'].div(7)))]

# Step 2: 为每组(原 ID)添加递增的 BusinessDay 偏移
n = out.groupby(level=0).cumcount()
out['PlannedStart'] = out['EarliestStart'] + n * pd.offsets.BusinessDay()

# Step 3: 提取星期名称(自动本地化,如 'Thursday')
out['Weekday'] = out['PlannedStart'].dt.day_name()

# Step 4: 计算每日分配工时 —— 前 N−1 天为 7h,最后一天为余数(若余数为 0,则最后两天均分?不,此处按题意设为 7)
s = out.pop('Hours').mod(7)
out['HoursSplitted'] = np.where(
    out.index.duplicated(keep='last') | s.eq(0),
    7.0,
    s
)

# 可选:格式化输出为欧洲风格(dd.MM.yyyy)及千分位逗号
out['PlannedStart'] = out['PlannedStart'].dt.strftime('%d.%m.%Y')
out['EarliestStart'] = out['EarliestStart'].dt.strftime('%d.%m.%Y')
out['HoursSplitted'] = out['HoursSplitted'].apply(lambda x: f"{x:.2f}".replace('.', ','))

⚠️ 注意事项与边界说明

  • BusinessDay 默认跳过周六、周日及节假日(如需自定义节假日,可传入 holidays= 参数);
  • groupby(level=0) 依赖 repeat 后索引保留原始位置,因此必须使用 .loc[...] 而非 .reindex(...);
  • s.eq(0) 判断余数为 0 的情况(如 14h → 2×7h),此时末尾两行均应为 7h,代码中通过 duplicated(keep='last') | s.eq(0) 确保倒数第二行也设为 7;
  • 若存在跨月/跨年排期,BusinessDay 仍能正确计算(如 2023-12-29 → 2024-01-02);
  • 输出顺序严格保持原始 ID 顺序,且同一 ID 的多行按 PlannedStart 递增排列,天然满足“最早可用”语义。

? 总结

该方案以声明式风格替代过程式逻辑,充分利用 pandas 的索引对齐与时间偏移能力,兼具性能与可读性。它不仅解决了示例中的 7 小时/天、跳过周末、全局顺序占用等约束,还可轻松扩展支持:
? 自定义日工作上限(修改除数 7);
? 多班次/多资源并行排程(增加分组维度);
? 加入优先级权重或截止日期约束(配合 sort_values 预排序)。

对于中等规模数据(

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

PHP 命令行脚本与自动化任务开发
PHP 命令行脚本与自动化任务开发

本专题系统讲解 PHP 在命令行环境(CLI)下的开发与应用,内容涵盖 PHP CLI 基础、参数解析、文件与目录操作、日志输出、异常处理,以及与 Linux 定时任务(Cron)的结合使用。通过实战示例,帮助开发者掌握使用 PHP 构建 自动化脚本、批处理工具与后台任务程序 的能力。

28

2025.12.13

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

3

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

7

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

30

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

2

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

8

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

3

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 46.4万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号