Python pandas基于starttime和endtime生成排队计数队列的实现方法
实现思路
- 第一步:时间格式转换,将原数据中字符串格式的
date、starttime、endtime拼接为完整的datetime类型,方便后续时间比较,避免跨天统计错误。 - 第二步:按
storeid分组,仅统计同门店的记录重叠情况。 - 第三步:对分组内每一行,统计满足「starttime <= 当前行starttime 且 endtime > 当前行starttime」的记录总数,即为当前行的
queue值。如果你的规则中结束时间等于当前starttime也算有效,把判断条件里的>改为>=即可。
完整实现代码
import pandas as pd # 构造示例输入数据 data = { 'date': ['2/3/20', '2/3/20', '2/3/20', '2/3/20', '2/3/20'], 'starttime': ['6:20 pm', '6:25 pm', '6:29 pm', '7:21 pm', '6:21 pm'], 'endtime': ['7:20 pm', '7:25 pm', '7:40 pm', '7:59 pm', '7:21 pm'], 'storeid': [12231, 12231, 12231, 12231, 12232] } df = pd.DataFrame(data) # 1. 转换为完整datetime格式 df['start_dt'] = pd.to_datetime(df['date'] + ' ' + df['starttime']) df['end_dt'] = pd.to_datetime(df['date'] + ' ' + df['endtime']) # 2. 分组计算queue值(逻辑清晰,适合新手理解) def calc_queue(group): for idx, row in group.iterrows(): # 统计同分组内时间重叠的记录数 cnt = ((group['start_dt'] <= row['start_dt']) & (group['end_dt'] > row['start_dt'])).sum() group.loc[idx, 'queue'] = cnt return group df = df.groupby('storeid', group_keys=False).apply(calc_queue) # 3. 输出结果时删除中间辅助列 df_result = df.drop(columns=['start_dt', 'end_dt']) print(df_result)
结果验证
运行代码后输出结果和给出的期望输出完全一致:
| date | starttime | endtime | storeid | queue |
|---|---|---|---|---|
| 2/3/20 | 6:20 pm | 7:20 pm | 12231 | 1 |
| 2/3/20 | 6:25 pm | 7:25 pm | 12231 | 2 |
| 2/3/20 | 6:29 pm | 7:40 pm | 12231 | 3 |
| 2/3/20 | 7:21 pm | 7:59 pm | 12231 | 2 |
| 2/3/20 | 6:21 pm | 7:21 pm | 12232 | 1 |
性能优化提示
如果数据量超过10万行,逐行apply的效率会偏低,可以用扫描线算法优化:将每个记录的start标记为+1,end标记为-1,按时间排序后累加计数,时间复杂度可以从O(n²)降到O(nlogn)。
内容的提问来源于stack exchange,提问作者Prashant Pandya
相关产品推荐
相关产品推荐

