pandas DataFrame日期匹配失败时如何获取相邻行的日期与价格值
pandas 日期缺省匹配获取相邻值方案
pandas 原生提供了专门针对有序时间序列的匹配方法,不需要手写遍历逻辑,就能实现「未命中时取相邻前序/后续值」的需求,核心基于二分查找实现,性能远高于自定义循环。
前置要求
使用相关方法前必须先做两步处理:
- 将日期列转换为
datetime64类型 - 按日期列做升序排序
具体实现方法
1. 单个日期查询:用索引的get_indexer方法
先将处理好的日期列设为DataFrame的索引,通过method参数指定未命中时的匹配规则:
method='ffill':未命中时取相邻的前一个可用日期对应的值method='bfill':未命中时取相邻的下一个可用日期对应的值(正好匹配你的需求)
参考代码:
import pandas as pd # 示例交易数据(仅含工作日,跳过周末/节假日) df = pd.DataFrame({ 'date': pd.to_datetime(['2024-05-06', '2024-05-07', '2024-05-08', '2024-05-10', '2024-05-13']), 'price': [102.3, 103.1, 102.8, 104.5, 105.2] }) # 预处理:设索引、排序 df = df.set_index('date').sort_index() def query_price(query_date): q_dt = pd.to_datetime(query_date) # 取匹配到的行位置,bfill对应取下一个可用日期 pos = df.index.get_indexer([q_dt], method='bfill')[0] return df.index[pos], df.iloc[pos]['price'] # 测试:查询存在的日期 print(query_price('2024-05-07')) # 输出 (Timestamp('2024-05-07 00:00:00'), 103.1) # 测试:查询不存在的周六日期2024-05-11 print(query_price('2024-05-11')) # 输出 (Timestamp('2024-05-13 00:00:00'), 105.2)
2. 批量日期查询:用pd.merge_asof
如果有一整列待查询的日期,不要写循环单条查询,直接用merge_asof做批量对齐,通过direction参数指定匹配规则:
direction='backward':未命中时取前一个可用值direction='forward':未命中时取下一个可用值(匹配你的需求)direction='nearest':未命中时取距离最近的可用值
参考代码:
# 待查询日期列表,包含周末等无数据日期 query_df = pd.DataFrame({ 'query_date': pd.to_datetime(['2024-05-07', '2024-05-09', '2024-05-11', '2024-05-12']) }) # 批量匹配 result = pd.merge_asof( query_df, df.reset_index(), left_on='query_date', right_on='date', direction='forward' ) print(result)
返回结果会自动为每一条查询日期,匹配到对应的下一个可用日期和price值。
注意事项
- 所有方法都要求日期序列是严格升序的,否则匹配结果会出错
- 待查询日期如果比数据集中所有日期都晚,
bfill/forward模式下会返回空值,记得提前做边界判断 - 不要手写for循环逐行比对日期,数据量超过1万行时性能差距会非常明显
内容的提问来源于stack exchange,提问作者sud
相关产品推荐
相关产品推荐

