如何用Lambda函数优化DataFrame工时拆分的行迭代效率?
高效处理工作时长溢出的Pandas方案
直接使用Lambda函数配合apply逐行处理并不能提升效率——因为apply(axis=1)本质还是逐行迭代,和你原来的for循环一样属于串行处理,没有利用Pandas的矢量化运算优势,大数据集下效率依然低下。
真正高效的做法是利用Pandas的分组+矢量化累积分配逻辑,避开逐行循环。
实现思路
你的需求本质是:将每个员工单日的总工作时长,按小时顺序分配,每小时最多60分钟,剩余时长顺延到下一小时,直到分配完毕。我们可以通过分组(按日期+员工编号)后计算总时长,再批量分配每个小时的时长,完全避免逐行循环。
代码实现
import pandas as pd # 构造示例数据(替换为你的实际DataFrame) df = pd.DataFrame({ '日期': ['14/07/2022']*6, '员工编号': [1123]*6, '小时': [12,13,14,15,16,17], '工作时长': [240,0,0,0,70,0] }) def split_hourly_duration(group): total_duration = group['工作时长'].sum() row_count = len(group) # 初始化每个小时的时长为60(最大值) allocated = [60] * row_count # 计算总时长减去前row_count-1个小时的最大容量后的剩余 remaining = total_duration - 60 * (row_count - 1) if remaining > 0: # 剩余时长分配到最后一个小时 allocated[-1] = remaining else: # 总时长不足以填满前row_count-1小时,按顺序分配 full_hours = total_duration // 60 remainder = total_duration % 60 allocated = [60]*full_hours + ([remainder] if full_hours < row_count else []) + [0]*(row_count - full_hours -1) group['工作时长'] = allocated return group # 按日期和员工分组处理,确保每个员工的单日小时序列独立 df = df.groupby(['日期', '员工编号'], group_keys=False).apply(split_hourly_duration)
结果验证
处理后得到的DataFrame与你的预期结果完全一致:
| 日期 | 员工编号 | 小时 | 工作时长 |
|---|---|---|---|
| 14/07/2022 | 1123 | 12 | 60 |
| 14/07/2022 | 1123 | 13 | 60 |
| 14/07/2022 | 1123 | 14 | 60 |
| 14/07/2022 | 1123 | 15 | 60 |
| 14/07/2022 | 1123 | 16 | 60 |
| 14/07/2022 | 1123 | 17 | 10 |
效率对比
- 原逐行循环/逐行lambda apply:时间复杂度O(n),且每行处理有额外开销,大数据集下速度极慢。
- 分组矢量化方案:利用Pandas的高效分组运算,时间复杂度远低于O(n),大数据集下性能提升显著。
内容的提问来源于stack exchange,提问作者Azza
相关产品推荐
相关产品推荐

