使用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
相关产品推荐
相关产品推荐

