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

使用Pandas计算两个时间戳间每小时的分钟数

嘿,我懂你想要实现的需求——把跨小时的时间戳范围拆解开,算出每个小时边界内实际占用的分钟数对吧?其实用pandas完全能搞定,不一定非得硬套resample,结合一些时间处理函数会更灵活。我给你一步步拆解具体的实现方法:

核心思路

我们需要先把原始的时间范围拆分成所有涉及到的完整小时区间,然后计算每个小时区间和原始时间范围的交集时长,最后转换成分钟数。

具体实现步骤

假设你有这样的输入数据(包含开始和结束时间的DataFrame):

import pandas as pd

# 示例数据
data = {
    'start': ['2024-05-20 13:45:00', '2024-05-20 15:10:00'],
    'end': ['2024-05-20 14:20:00', '2024-05-20 17:35:00']
}
df = pd.DataFrame(data)
# 转换为datetime类型
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])

步骤1:生成每个时间范围覆盖的所有小时边界

对于每一行的起止时间,我们需要生成从开始时间所在小时的整点,到结束时间所在小时的整点(甚至下一个整点)的序列,这样就能得到所有涉及到的小时区间:

def get_hour_intervals(row):
    # 取开始时间的整点
    start_hour = row['start'].floor('H')
    # 取结束时间的整点
    end_hour = row['end'].floor('H')
    
    # 处理结束时间刚好是整点的情况,避免多生成一个空区间
    if row['end'].minute == 0 and row['end'].second == 0:
        hours = pd.date_range(start_hour, end_hour, freq='H')
    else:
        hours = pd.date_range(start_hour, end_hour + pd.Timedelta(hours=1), freq='H')
    
    # 生成每个小时的区间:(当前整点, 下一个整点)
    hour_intervals = [(h, h + pd.Timedelta(hours=1)) for h in hours[:-1]]
    return hour_intervals

# 给每行添加对应的小时区间列表
df['hour_intervals'] = df.apply(get_hour_intervals, axis=1)

步骤2:计算每个小时区间的重叠分钟数

接下来,对每个小时区间,计算它和原始起止时间的重叠部分,再把时长转换成分钟:

def calculate_minutes_per_hour(row):
    hour_minute_list = []
    for hour_start, hour_end in row['hour_intervals']:
        # 交集的开始是两个时间的较大值,结束是两个时间的较小值
        overlap_start = max(row['start'], hour_start)
        overlap_end = min(row['end'], hour_end)
        # 计算重叠时长(分钟)
        minutes = (overlap_end - overlap_start).total_seconds() / 60
        hour_minute_list.append({
            'hour': hour_start.strftime('%Y-%m-%d %H:00:00'),
            'minutes': minutes
        })
    return hour_minute_list

# 生成每个小时的分钟数结果
df['hour_minutes'] = df.apply(calculate_minutes_per_hour, axis=1)
# 展开列表,把每个小时的结果拆成单独行
df_exploded = df.explode('hour_minutes').reset_index(drop=True)
# 把字典格式的结果拆成单独列
df_exploded = pd.concat([df_exploded.drop('hour_minutes', axis=1), 
                         df_exploded['hour_minutes'].apply(pd.Series)], axis=1)

步骤3:查看最终结果

运行后,df_exploded会输出你想要的格式:

start                 end                 hour  minutes
0 2024-05-20 13:45:00 2024-05-20 14:20:00  2024-05-20 13:00:00     15.0
1 2024-05-20 13:45:00 2024-05-20 14:20:00  2024-05-20 14:00:00     20.0
2 2024-05-20 15:10:00 2024-05-20 17:35:00  2024-05-20 15:00:00     50.0
3 2024-05-20 15:10:00 2024-05-20 17:35:00  2024-05-20 16:00:00     60.0
4 2024-05-20 15:10:00 2024-05-20 17:35:00  2024-05-20 17:00:00     35.0
补充小提示
  • 如果你的数据量很大,用apply可能效率稍低,可以考虑用矢量化操作或者结合pd.MultiIndex来优化性能。
  • 如果你坚持想用resample,可以先把每个时间范围拆成每分钟的时间点,再按小时resample计数,但这种方法对于长时间段来说内存开销会很大,不如上面的方法高效。

内容的提问来源于stack exchange,提问作者Priva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:14:10