如何使用Python/pandas创建包含连续停留日期的日期列
实现方法
核心逻辑是先按Id分组拿到每个分组的日期区间起点(到达日期)和终点(该组最晚停留日期),再生成区间内的连续日期序列展开为单行单条记录即可,全程使用pandas内置方法实现,性能远高于逐行循环写法。
完整代码
首先确保日期列已转换为datetime类型,这是pandas做日期运算的前提:
import pandas as pd # ---------------------- # 实际使用时替换为读取自有数据的逻辑 # df = pd.read_csv("your_data.csv") # 以下为示例数据构造,复现测试可直接运行 df = pd.DataFrame({ 'Id': [1,1,1,2,2], 'd_of_arr': ['2021-12-03']*3 + ['2021-12-09']*2, 'd_of_sty': ['2021-12-04','2021-12-05','2021-12-06','2021-12-10','2021-12-11'] }) # ---------------------- # 转换日期列为标准datetime格式 df[['d_of_arr', 'd_of_sty']] = df[['d_of_arr', 'd_of_sty']].apply(pd.to_datetime) # 按Id分组,取每个组的到达日期(同组Id到达日期一致,取first即可)、最大停留日期作为区间端点 date_ranges = df.groupby('Id', as_index=False).agg( arr_date = ('d_of_arr', 'first'), max_stay_date = ('d_of_sty', 'max') ) # 为每个分组生成按天连续的日期序列 date_ranges['dates'] = date_ranges.apply( lambda row: pd.date_range(start=row['arr_date'], end=row['max_stay_date'], freq='D'), axis=1 ) # 展开日期序列为单独行,得到最终结果 result = date_ranges[['Id', 'dates']].explode('dates', ignore_index=True)
运行后result的输出和预期效果完全一致:
| Id | dates |
|---|---|
| 1 | 2021-12-03 |
| 1 | 2021-12-04 |
| 1 | 2021-12-05 |
| 1 | 2021-12-06 |
| 2 | 2021-12-09 |
| 2 | 2021-12-10 |
| 2 | 2021-12-11 |
可选调整项
- 如果同个
Id下存在多个不同的到达日期,把聚合时arr_date的聚合规则从first改成min,会自动取最早的到达日期作为序列起点 - 如果需要输出字符串格式的日期而非datetime类型,最后追加一行代码即可:
result['dates'] = result['dates'].dt.strftime('%Y-%m-%d') - 如果不需要按天连续,比如要隔1天生成一个日期,把
pd.date_range里的freq='D'改成freq='2D'即可,其他频率规则可直接使用pandas支持的日期偏移别名。
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

