Python中无需循环基于前序行生成人员分配计数新列的实现方案
人员分配计数实现方案
前置数据处理
首先需要将表中的12小时制时间字符串转换为可比较的数值格式(距离0点的分钟数),便于后续时间比较:
import pandas as pd import heapq import numpy as np # 导入数据,可替换为自己的读表逻辑如pd.read_csv df = pd.DataFrame({ 'TimeIn': ['01:23AM', '01:34AM', '01:43AM', '02:01AM', '02:34AM', '02:39AM', '02:56AM'], 'TimeOut': ['01:45AM', '01:53AM', '01:59AM', '02:09AM', '03:11AM', '02:48AM', '03:12AM'] }) # 时间转分钟数工具函数 def time_to_min(time_str): t = pd.to_datetime(time_str).time() return t.hour * 60 + t.minute df['time_in'] = df['TimeIn'].apply(time_to_min) df['time_out'] = df['TimeOut'].apply(time_to_min)
高效最小堆实现方案
该方案为经典的任务调度/会议室分配最优实现,时间复杂度为O(n log k),其中n为数据总条数,k为所需最大人员数,百万级数据量可在秒级完成运算:
heap = [] counter_res = [] for in_t, out_t in zip(df['time_in'], df['time_out']): # 弹出所有已空闲的人员记录 while heap and heap[0][0] <= in_t: heapq.heappop(heap) if not heap: # 无空闲人员时新增编号 assign_id = len(heap) + 1 else: # 取最早空闲的人员编号 assign_id = heapq.heappop(heap)[1] # 压入当前人员的最新结束时间 heapq.heappush(heap, (out_t, assign_id)) counter_res.append(assign_id) df['Counter'] = counter_res # 删除辅助列,输出最终结果 df = df.drop(columns=['time_in', 'time_out'])
运行后得到的Counter列和预期输出完全一致。
纯pandas向量化无循环方案说明
由于人员分配需要维护「已分配人员的结束时间」状态,纯向量化实现的代码复杂度较高,且实际运行性能对比最小堆方案没有明显优势。如果确实需要避免Python层循环,可基于numba对最小堆逻辑做JIT编译,运行效率可提升5-10倍,适合超大数据量场景。
内容的提问来源于stack exchange,提问作者Abhishek Singh
相关产品推荐
相关产品推荐

