如何基于案例起止日期统计三年内每周的案例数量?
生成每周活跃案例数的DataFrame解决方案
嗨,别担心,新手阶段处理这类时间序列统计需求很正常~我来一步步帮你实现这个目标!
核心思路
我们需要先生成目标三年内的所有周区间,然后统计每个周内时间区间与该周有重叠的案例数量(即案例的Start_Date ≤ 周结束日期,且End_Date ≥ 周开始日期)。
步骤实现(使用Pandas)
1. 导入依赖库并准备数据
首先导入pandas,并将你的数据转换为Pandas DataFrame,同时把日期列转为datetime类型(这是时间统计的基础):
import pandas as pd from datetime import datetime # 你的示例数据(实际使用时可以用pd.read_csv读取你的数据集) data = { 'ID': [1,2,3,4,5,6,7,8], 'Start_Date': ['2015-01-04','2015-01-05','2015-01-07','2015-01-12','2015-01-15','2015-01-21','2015-01-21','2015-01-22'], 'End_Date': ['2017-11-02','2015-10-26','2015-03-04','2016-05-17','2015-04-08','2016-07-31','2015-07-16','2015-03-03'] } df = pd.DataFrame(data) # 将日期列转换为datetime类型 df['Start_Date'] = pd.to_datetime(df['Start_Date']) df['End_Date'] = pd.to_datetime(df['End_Date'])
2. 生成三年内的所有周区间
我们可以根据数据的实际时间范围(或者固定三年)生成每周的起始和结束日期:
# 方法1:固定三年范围(2015-01-01至2017-12-31) start_range = datetime(2015, 1, 1) end_range = datetime(2017, 12, 31) # 方法2:根据数据集自动获取时间范围(更灵活) # start_range = df['Start_Date'].min().floor('D') # end_range = df['End_Date'].max().ceil('D') # 生成每周起始日期,freq='W-MON'表示每周一为周起始,可改为'W-SUN'(周日起始) weekly_starts = pd.date_range(start=start_range, end=end_range, freq='W-MON') # 创建周区间DataFrame,包含周起始、周结束日期 weekly_df = pd.DataFrame({ 'Week_Start': weekly_starts, 'Week_End': weekly_starts + pd.Timedelta(days=6) # 周结束为起始+6天 })
3. 统计每周的活跃案例数
这里提供两种方法,适合不同数据量场景:
方法A:简单易用的Apply方法(适合中小数据集,比如你的2000行)
# 定义函数:计算单个周区间内的活跃案例数 def count_active(row): # 判断案例时间区间与当前周是否重叠 is_active = (df['Start_Date'] <= row['Week_End']) & (df['End_Date'] >= row['Week_Start']) return is_active.sum() # 统计True的数量 # 应用到每个周 weekly_df['Active_Cases'] = weekly_df.apply(count_active, axis=1)
方法B:向量化方法(更高效,适合超大数据集)
用Numpy广播实现批量判断,速度比Apply快很多:
# 将日期转换为timestamp格式,便于广播运算 case_starts = df['Start_Date'].values.astype('datetime64[ns]') case_ends = df['End_Date'].values.astype('datetime64[ns]') week_starts = weekly_df['Week_Start'].values.astype('datetime64[ns]') week_ends = weekly_df['Week_End'].values.astype('datetime64[ns]') # 批量判断每个案例在每个周是否活跃 active_mask = (case_starts[:, None] <= week_ends) & (case_ends[:, None] >= week_starts) # 按周求和,得到每周活跃案例数 weekly_df['Active_Cases'] = active_mask.sum(axis=0)
4. 优化结果展示(可选)
可以添加标准的周编号(如2015-W01),让结果更清晰:
weekly_df['Week_Number'] = weekly_df['Week_Start'].dt.strftime('%Y-W%U') # 展示最终结果的前几行 print(weekly_df[['Week_Number', 'Week_Start', 'Week_End', 'Active_Cases']].head())
最终输出的DataFrame就会清晰展示每个周的起始/结束日期,以及对应的活跃案例数量啦!
内容的提问来源于stack exchange,提问作者yfa
相关产品推荐
相关产品推荐

