在Pandas中查找月度各日最繁忙的1小时时段
解决月度每日1小时窗口最大行程数问题
嘿,我来帮你搞定这个问题!首先得明确核心需求:找出每个月的每一天里,任意连续1小时区间内的最大行程数量——我会覆盖几种常见的场景(毕竟有时候需求表述可能存在歧义),你可以根据实际情况选对应的方法。
第一步:数据预处理
不管哪种场景,第一步都是把字符串格式的时间列转成可计算的datetime类型,同时过滤掉跨天的行程(题目明确要求行程起止均在当日):
import pandas as pd import numpy as np # 假设你的原始DataFrame名为df df['trip_start'] = pd.to_datetime(df['trip_start']) df['trip_end'] = pd.to_datetime(df['trip_end']) # 过滤掉跨天的行程(确保行程起止都在同一天) df = df[df['trip_start'].dt.date == df['trip_end'].dt.date] # 新增日期列,方便按天分组计算 df['date'] = df['trip_start'].dt.date
场景1:统计与1小时窗口有重叠的最大行程数
这是最常见的需求:某个1小时区间内,只要行程的时间和该区间有重叠(不管是部分还是全部),就算入数量,我们要找这个数量的最大值。
实现思路
最大的重叠行程数一定会出现在某个行程的开始时间、结束时间,或者开始时间往前1小时、结束时间往后1小时的位置(这些是行程进入/离开窗口的临界点)。我们只需要检查这些临界点对应的1小时窗口,就能找到最大值。
代码实现
def max_overlapping_trips(day_df): # 把时间转成时间戳(单位:秒),方便数值计算 starts = day_df['trip_start'].values.astype(np.int64) // 10**9 ends = day_df['trip_end'].values.astype(np.int64) // 10**9 hour_sec = 3600 # 1小时的秒数 # 生成所有需要检查的临界点 check_points = np.concatenate([starts, ends, starts - hour_sec, ends + hour_sec]) # 过滤掉超出当日范围的点(窗口必须完全在当天内) day_start = day_df['trip_start'].min().floor('D').value // 10**9 day_end = day_start + 24 * hour_sec check_points = check_points[(check_points >= day_start) & (check_points + hour_sec <= day_end)] max_count = 0 for t in check_points: # 统计满足:行程开始<=窗口结束,且行程结束>=窗口开始的数量 count = np.sum((starts <= t + hour_sec) & (ends >= t)) if count > max_count: max_count = count return max_count # 按日期分组计算,得到每日的最大重叠行程数 daily_max_overlap = df.groupby('date').apply(max_overlapping_trips).reset_index(name='max_overlapping_trips')
场景2:统计完全包含在1小时窗口内的最大行程数
如果需求是:只有整个行程都落在1小时窗口内才算入数量,那只需要调整统计条件即可:
代码实现
def max_contained_trips(day_df): starts = day_df['trip_start'].values.astype(np.int64) // 10**9 ends = day_df['trip_end'].values.astype(np.int64) // 10**9 hour_sec = 3600 check_points = np.concatenate([starts, ends, starts - hour_sec, ends + hour_sec]) day_start = day_df['trip_start'].min().floor('D').value // 10**9 day_end = day_start + 24 * hour_sec check_points = check_points[(check_points >= day_start) & (check_points + hour_sec <= day_end)] max_count = 0 for t in check_points: # 统计满足:行程开始>=窗口开始,且行程结束<=窗口结束的数量 count = np.sum((starts >= t) & (ends <= t + hour_sec)) if count > max_count: max_count = count return max_count daily_max_contained = df.groupby('date').apply(max_contained_trips).reset_index(name='max_contained_trips')
场景3:统计1小时内开始的最大行程数
如果需求是:某个1小时区间内,有多少个行程是在这个区间内开始的,找这个数量的最大值,那可以用熊猫的滚动窗口功能,更简洁:
代码实现
def max_starts_per_hour(day_df): # 按行程开始时间排序 day_df_sorted = day_df.sort_values('trip_start') # 用1小时的滚动窗口统计开始的行程数 rolling_counts = day_df_sorted.rolling('1h', on='trip_start').count()['trip_start'] return rolling_counts.max() daily_max_starts = df.groupby('date').apply(max_starts_per_hour).reset_index(name='max_starts_per_hour')
内容的提问来源于stack exchange,提问作者user9610943
相关产品推荐
相关产品推荐

