如何在Python中获取两个日期间的每周时间区间并返回DataFrame
实现方案
完整可运行代码
import pandas as pd import datetime from dateutil.relativedelta import relativedelta def get_date_intervals(st_dt, end_dt, intv=7): # 统一转换输入为datetime类型 st_dt = pd.to_datetime(st_dt) end_dt = pd.to_datetime(end_dt) # 按自然月逐个处理,避免跨月 current_month_start = st_dt.replace(day=1, hour=0, minute=0, second=0) while current_month_start <= end_dt: # 计算当前月最后一天的23:59:59 current_month_end = (current_month_start + relativedelta(months=1) - datetime.timedelta(days=1)).replace(hour=23, minute=59, second=59) # 当月处理的起始时间:第一个月取传入的起始时间,其余月份取当月1号0点 period_start = max(st_dt, current_month_start) while period_start <= min(end_dt, current_month_end): # 计算当前区间的理论结束时间 period_end_theory = period_start + datetime.timedelta(days=intv) # 实际结束时间取理论结束时间、当月最后一天、全局结束时间的最小值,统一固定为23:59:59 period_end = min(period_end_theory, current_month_end, end_dt).replace(hour=23, minute=59, second=59) # 生成器返回区间 yield (period_start, period_end) # 下一个区间的起始时间是当前结束时间+1天的0点 period_start = period_end + datetime.timedelta(days=1) # 处理下一个月 current_month_start = current_month_start + relativedelta(months=1) # 调用示例 if __name__ == '__main__': first_date = '2021-01-01 00:00:00' end_date = '2021-12-31 23:59:59' # 生成区间并转DataFrame interval_list = list(get_date_intervals(first_date, end_date, intv=7)) df_out = pd.DataFrame(interval_list, columns=['Start_Date', 'End_Date']) # 如果需要输出字符串格式可开启下面两行 # df_out['Start_Date'] = df_out['Start_Date'].dt.strftime('%Y-%m-%d %H:%M:%S') # df_out['End_Date'] = df_out['End_Date'].dt.strftime('%Y-%m-%d %H:%M:%S') print(df_out)
逻辑说明
- 按自然月拆分处理逻辑,从根源避免区间跨月
- 所有结束时间统一设置为23:59:59,不需要额外的奇偶行判断逻辑
- 自动适配全局起止时间,不会生成超出传入范围的区间
- 支持自定义间隔天数,修改
intv参数即可调整区间长度
原有代码问题修正
- 周结束时间计算偏移:原代码加7天得到的是下一日0点,正确逻辑是直接对齐23:59:59时间戳
- 奇偶行修改结束时间的逻辑完全冗余,统一设置所有End_Date的时分秒即可符合要求
pd.DataFrame.append方法已在pandas 2.0+版本弃用,生成器方案性能更高、写法更简洁
内容的提问来源于stack exchange,提问作者VJ Sojitra
相关产品推荐
相关产品推荐

