如何按自定义时长窗口分组统计Pandas DataFrame患者就诊数
解决方案
以下是实现需求的函数代码,包含两种实现方式(直观版和高效版):
直观实现(适合小数据集)
import pandas as pd def group_by_duration(df, x, y): # 获取数据中的最小和最大日期(仅日期部分) min_date = df['demandTime'].dt.date.min() max_date = df['demandTime'].dt.date.max() # 生成所有窗口的起始时间:从min_date的x时开始,到max_date的x时,每天一个 window_starts = pd.date_range( start=f"{min_date} {x}:00:00", end=f"{max_date} {x}:00:00", freq='D' ) # 构造窗口的起始和结束时间DataFrame windows = pd.DataFrame({ 'start': window_starts, 'end': window_starts + pd.Timedelta(hours=y) }) # 统计每个窗口内的患者数量 windows['total_patient'] = windows.apply( lambda row: df[ (df['demandTime'] >= row['start']) & (df['demandTime'] < row['end']) ]['patientVisit_id'].count(), axis=1 ) # 整理输出格式:提取起始日期作为ds列,保留患者数 output_df = pd.DataFrame({ 'ds': windows['start'].dt.date, 'total_patient': windows['total_patient'] }) return output_df
高效向量化实现(适合大数据集)
如果数据集较大,apply循环效率较低,可以使用IntervalIndex和pd.cut实现向量化统计:
import pandas as pd def group_by_duration(df, x, y): min_date = df['demandTime'].dt.date.min() max_date = df['demandTime'].dt.date.max() window_starts = pd.date_range( start=f"{min_date} {x}:00:00", end=f"{max_date} {x}:00:00", freq='D' ) window_ends = window_starts + pd.Timedelta(hours=y) # 创建区间索引,左闭右开(匹配需求中的时间范围) intervals = pd.IntervalIndex.from_arrays(window_starts, window_ends, closed='left') # 将每个demandTime分配到对应的区间,统计数量 count_series = pd.cut(df['demandTime'], bins=intervals).value_counts() # 确保所有窗口都被包含,缺失的窗口填充0 count_series = count_series.reindex(intervals, fill_value=0) # 整理输出 output_df = pd.DataFrame({ 'ds': window_starts.dt.date, 'total_patient': count_series.values }) return output_df
测试验证
使用你提供的示例数据测试:
df = pd.DataFrame({ "patientVisit_id": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "demandTime": pd.to_datetime([ "2023-06-06 06:00:00", "2023-06-06 07:00:00", "2023-06-06 08:00:00", "2023-06-06 09:00:00", "2023-06-06 10:00:00", "2023-06-07 02:00:00", "2023-06-07 12:00:00", "2023-06-07 13:00:00", "2023-06-07 14:00:00" ]) }) result = group_by_duration(df, x=6, y=22) print(result)
输出结果与你的示例完全一致:
ds total_patient 0 2023-06-06 6 1 2023-06-07 3
关键逻辑说明
- 窗口生成:从数据的最小日期的X时开始,到最大日期的X时结束,每天生成一个窗口起始点,确保覆盖所有需要统计的时间范围。
- 时间范围判断:每个窗口的时间范围是
[start, start+Y小时),左闭右开的逻辑避免了时间点重复统计(比如刚好落在窗口结束时间的记录不会被计入当前窗口)。 - 统计逻辑:根据
patientVisit_id的记录数统计患者数量(因为每个ID对应一条就诊记录,用count()即可;如果存在重复ID,可改用nunique()统计唯一患者数)。
内容的提问来源于stack exchange,提问作者MIMIGA
相关产品推荐
相关产品推荐

