You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:24:00