如何在Pandas中不考虑年份筛选指定日期前后区间的数据?
解决Pandas日期筛选的跨年问题及溢出错误
错误原因分析
你遇到的OutOfBoundsDatetime错误,是因为1400-01-01超出了Pandas datetime64[ns]类型的支持范围——该类型基于纳秒时间戳,仅能表示1677-09-21 00:12:43到2262-04-11 23:47:16之间的日期,早于1677年的日期会触发溢出。
需求实现思路
要筛选指定日期(如1月1日)前后Δ天(如±2天)的数据,且覆盖跨年场景(如12月30、31日),核心是忽略年份,仅比较月日的相对时间差,不需要使用早于1677年的日期。
下面提供两种可行的实现方法:
方法一:利用dayofyear处理跨年
通过日期在一年中的天数(dayofyear)来判断,年初的前Δ天对应上一年的末尾天数:
import pandas as pd # 读取数据(保持原有代码) dfr = pd.read_csv('test.csv', sep=',', index_col=0, parse_dates=True) # 配置参数:目标日期(1月1日)、前后天数Δ target_month, target_day = 1, 1 delta = 2 # 计算目标日期的dayofyear(用闰年确保覆盖2月29日) target_doy = pd.Timestamp(f'2020-{target_month}-{target_day}').dayofyear # 闰年一年有366天,这里用基准闰年统一处理 max_doy = 366 # 生成需要筛选的dayofyear范围:上一年末尾的Δ天 + 当年开头的Δ+1天(含目标日) start_range = max_doy - delta + 1 mask = (dfr.index.dayofyear >= start_range) | (dfr.index.dayofyear <= target_doy + delta) # 获取结果 res = dfr[mask]['qq'].tolist() print(res) # 输出: [1,2,3,8,9,10,15,16,17,22,23]
方法二:提取月日构造基准年日期
将所有日期的月日提取出来,用同一个基准年(如2020年,闰年)构造新日期,再计算与目标日期的相对天数差:
import pandas as pd dfr = pd.read_csv('test.csv', sep=',', index_col=0, parse_dates=True) target_month, target_day = 1, 1 delta = 2 # 用闰年作为基准年,避免2月29日的转换问题 base_year = 2020 target_date = pd.Timestamp(f'{base_year}-{target_month}-{target_day}') # 为每个原始日期构造基准年的对应日期 dfr['base_date'] = pd.to_datetime(dfr.index.strftime(f'{base_year}-%m-%d')) # 计算天数差,用模366处理跨年循环 day_diff = (dfr['base_date'] - target_date).dt.days % 366 # 筛选:差≤delta(目标日后Δ天) 或 差≥366-delta(目标日前Δ天) mask = (day_diff <= delta) | (day_diff >= 366 - delta) res = dfr[mask]['qq'].tolist() print(res) # 输出: [1,2,3,8,9,10,15,16,17,22,23]
内容的提问来源于stack exchange,提问作者diedro
相关产品推荐
相关产品推荐

