基于两列日期过滤Pandas DataFrame并处理交易日问题
交易日筛选的正确实现方案
1. 基础预处理:日期列转换与排序
首先必须确保日期列是可处理的datetime类型,且数据按交易日有序排列,这是后续计算的核心前提:
import pandas as pd import numpy as np # 转换TradeDate为datetime格式 df['TradeDate'] = pd.to_datetime(df['TradeDate']) # 按交易日排序并重置索引,避免原索引干扰 df_sorted = df.sort_values('TradeDate').reset_index(drop=True)
2. 构建有序交易日索引
提取所有唯一交易日生成索引对象,用于快速定位日期位置:
trade_dates = df_sorted['TradeDate'].unique() date_index = pd.Index(trade_dates)
3. 两种常见筛选场景的实现
场景1:筛选单个/指定多个交易日的前后5个交易日
比如要筛选2023-06-15前后5个交易日的数据:
target_date = pd.to_datetime('2023-06-15') # 获取目标日期在交易日索引中的位置 pos = date_index.get_loc(target_date) # 处理边界:避免索引越界(比如第一个日期前无足够交易日) start_pos = max(0, pos - 5) end_pos = min(len(date_index) - 1, pos + 5) # 获取符合条件的交易日范围 selected_dates = date_index[start_pos:end_pos + 1] # 筛选最终数据 filtered_df = df_sorted[df_sorted['TradeDate'].isin(selected_dates)]
场景2:为每笔交易筛选其前后5个交易日(合并去重)
如果需要保留所有交易对应的前后5个交易日数据,最终合并去重:
# 获取每笔交易日期在索引中的位置 positions = date_index.get_indexer(df_sorted['TradeDate']) # 计算每个日期对应的前后5个交易日的索引范围 start_positions = np.maximum(0, positions - 5) end_positions = np.minimum(len(date_index) - 1, positions + 5) # 收集所有需要保留的交易日索引并去重 selected_indices = np.unique(np.concatenate([np.arange(s, e+1) for s, e in zip(start_positions, end_positions)])) selected_dates = date_index[selected_indices] # 筛选结果 filtered_df = df_sorted[df_sorted['TradeDate'].isin(selected_dates)]
核心注意事项
- 禁用自然日计算:交易日剔除了周末和节假日,直接用
date + pd.Timedelta(days=5)会包含非交易日,导致筛选错误。 - 强制边界处理:当目标日期是序列前5个或后5个交易日时,必须限制索引范围,避免抛出越界异常。
- 大数量优化:数据量极大时,优先使用向量化操作(如上述场景2的numpy实现)替代循环,大幅提升运行效率。
内容的提问来源于stack exchange,提问作者IamaNOOB
相关产品推荐
相关产品推荐

