Pandas如何根据已预约时间段计算球场的空闲互补时间范围
实现思路
- 先将时间列转换为pandas datetime格式,方便时间计算
- 按球场名称分组,单独处理每个球场的预定记录
- 每个球场的预定记录按开始时间排序后,计算相邻预定的间隔,再补充营业开始到首个预定、最后一个预定到营业结束的空闲时间段
- 最后合并所有球场的结果得到最终空闲时间段表
完整实现代码
import pandas as pd # 原始数据 df = pd.DataFrame( [ {'court_name': 'Court 1', 'reserved_fr': '2021-11-15T08:00:00', 'reserved_to': '2021-11-15T12:00:00'}, {'court_name': 'Court 1', 'reserved_fr': '2021-11-15T15:00:00', 'reserved_to': '2021-11-15T16:00:00'}, {'court_name': 'Court 1', 'reserved_fr': '2021-11-15T16:00:00', 'reserved_to': '2021-11-15T21:00:00'}, {'court_name': 'Court 2', 'reserved_fr': '2021-11-15T20:00:00', 'reserved_to': '2021-11-15T21:00:00'} ] ) # 转换时间列为datetime类型 df['reserved_fr'] = pd.to_datetime(df['reserved_fr']) df['reserved_to'] = pd.to_datetime(df['reserved_to']) def get_free_time(group): # 按预定开始时间排序 group = group.sort_values('reserved_fr').reset_index(drop=True) court_name = group['court_name'].iloc[0] # 取当前日期,构造营业开始、结束时间 date = group['reserved_fr'].iloc[0].floor('D') business_start = date + pd.Timedelta(hours=7) business_end = date + pd.Timedelta(hours=23) free_periods = [] # 第一段空闲:营业开始到第一个预定开始 first_reserve_start = group['reserved_fr'].iloc[0] if business_start < first_reserve_start: free_periods.append((court_name, business_start, first_reserve_start)) # 中间空闲段:前一个预定结束到下一个预定开始 for i in range(1, len(group)): prev_end = group['reserved_to'].iloc[i-1] curr_start = group['reserved_fr'].iloc[i] if prev_end < curr_start: free_periods.append((court_name, prev_end, curr_start)) # 最后一段空闲:最后一个预定结束到营业结束 last_reserve_end = group['reserved_to'].iloc[-1] if last_reserve_end < business_end: free_periods.append((court_name, last_reserve_end, business_end)) return pd.DataFrame(free_periods, columns=['court_name', 'free_from', 'free_to']) # 分组计算后合并结果 free_df = df.groupby('court_name', group_keys=False).apply(get_free_time).reset_index(drop=True) # 打印结果 print(free_df)
输出结果
运行上述代码得到的结果与示例完全一致:
court_name free_from free_to 0 Court 1 2021-11-15 07:00:00 2021-11-15 08:00:00 1 Court 1 2021-11-15 12:00:00 2021-11-15 15:00:00 2 Court 1 2021-11-15 21:00:00 2021-11-15 23:00:00 3 Court 2 2021-11-15 07:00:00 2021-11-15 20:00:00 4 Court 2 2021-11-15 21:00:00 2021-11-15 23:00:00
补充说明:如果原始数据中存在重叠、交叉的预定记录,可以先对每个球场的预定时间段做合并处理,再执行上述空闲时间计算逻辑,避免结果出现异常。
内容的提问来源于stack exchange,提问作者user3225309
相关产品推荐
相关产品推荐

