当前位置: 首页 > ai >正文

使用 merge_asof 实现高效的时间序列匹配(无需循环)

pd.merge_asof() 是 Pandas 中用于 按最近键值合并两个表 的高效函数,特别适合处理时间序列、数值区间或非精确匹配的场景。以下是其核心用法和示例:


核心功能
根据一个键(如日期或数值),在右表中找到 最接近左表键值 的记录,并合并到左表。常用于:
• 合并价格变动记录(如订单时间匹配最新价格)

• 匹配时间戳相近的日志数据

• 处理数值区间(如温度区间匹配传感器ID)


基础语法

pd.merge_asof(left,                   # 左表(主表)right,                  # 右表(查找表)on=None,                # 键列名(左右表同名时用)left_on=None,           # 左表键列名right_on=None,          # 右表键列名left_index=False,       # 是否用左表索引作为键right_index=False,      # 是否用右表索引作为键by=None,                # 分组键(如按多个列分组匹配)suffixes=("_x", "_y"),  # 列名后缀tolerance=None,         # 允许的最大时间/数值差allow_exact_matches=True,  # 是否允许精确匹配direction="backward"    # 匹配方向:backward/forward/nearest
)

关键参数详解

参数说明示例值
left_on左表的键列名'order_date'
right_on右表的键列名'price_update_date'
by分组匹配的列(类似 SQL 的 GROUP BY)['product_id', 'region']
direction匹配方向:
- backward:右表键 ≤ 左表键(默认)
- forward:右表键 ≥ 左表键
- nearest:最接近左表键
'forward'
tolerance允许的键值最大差值(时间差或数值差)pd.Timedelta(days=7)(时间差)
100(数值差)

使用步骤
1. 数据准备
确保左表和右表已按 键列排序(否则报错):

# 示例数据:订单表(左表)和价格表(右表)
left = pd.DataFrame({'order_id': [1, 2, 3],'order_date': ['2023-01-05', '2023-01-10', '2023-01-15'],'product_id': ['A', 'B', 'A']
})right = pd.DataFrame({'price_update_date': ['2023-01-01', '2023-01-08', '2023-01-12'],'product_id': ['A', 'B', 'A'],'price': [100, 200, 150]
})# 转换为 datetime 类型并排序
left['order_date'] = pd.to_datetime(left['order_date'])
right['price_update_date'] = pd.to_datetime(right['price_update_date'])
right = right.sort_values('price_update_date')

2. 基本合并(按最近日期匹配价格)

merged = pd.merge_asof(left=left.sort_values('order_date'),right=right,left_on='order_date',right_on='price_update_date',by='product_id',        # 按产品分组匹配direction='backward'    # 取价格更新日期 ≤ 订单日期的最近记录
)

3. 结果输出

order_idorder_dateproduct_idprice_update_dateprice
12023-01-05A2023-01-01100
22023-01-10B2023-01-08200
32023-01-15A2023-01-12150

高级场景
1. 限制匹配范围(tolerance
只匹配 3 天内的价格更新:

merged = pd.merge_asof(left=left,right=right,left_on='order_date',right_on='price_update_date',by='product_id',direction='backward',tolerance=pd.Timedelta(days=3)  # 订单日期 - 价格日期 ≤ 3天
)

2. 向前匹配(direction='forward'
找订单日期之后最早的价格更新:

merged = pd.merge_asof(left=left,right=right,direction='forward'  # 取价格更新日期 ≥ 订单日期的最近记录
)

3. 多列分组(by=[col1, col2]
按产品 + 区域匹配价格:

merged = pd.merge_asof(left=left,right=right,left_on='order_date',right_on='price_update_date',by=['product_id', 'region']  # 多列分组
)

注意事项

  1. 必须预先排序:左表和右表的键列必须按升序排列。
  2. 数据类型一致:键列(如日期、数值)需确保类型相同。
  3. 重复键处理:右表中同一键值的多条记录会取最后一条。

对比普通 merge

场景merge_asofmerge
精确匹配❌ 不支持✅ 支持
最近匹配✅ 高效❌ 需复杂操作
数值区间匹配✅ 适用❌ 需筛选

掌握 merge_asof 能大幅提升时间序列或区间匹配场景的处理效率!

http://www.xdnf.cn/news/4657.html

相关文章:

  • rest_framework学习之认证 权限
  • 【软件设计师:数据库】13.数据库控制与安全
  • vite 代理 websocket
  • 稳定性_李雅普诺夫——Lyapunov直接法
  • 网络靶场基础知识
  • 是更换Window资源管理器的时候了-> Files-community/Files
  • 涨薪技术|0到1学会性能测试第53课-Tomcat配置
  • Python中的re库详细用法与代码解析
  • 在Lua中使用轻量级userdata在C/C++之间传递数据和调用函数
  • 探讨关于智能体(Agent)结合 Dify、大语言模型(LLM)以及 Qwen-3 模型的项目或概念
  • C++-缺省参数
  • 如何在Jmeter中调用C程序?
  • 【软考-高级】【信息系统项目管理师】【论文基础】采购管理过程输入输出及工具技术的使用方法
  • 永久免费的小工具,内嵌微软接口
  • AWS LB target group 监听端口的增加 (TCP还是UDP)
  • Redis实现分布式获取全局唯一自增ID的案例。
  • Dify X 奇墨科技,让AI大模型从“巨头专属”变为“触手可及”
  • Windows系统下使用Kafka和Zookeeper,Python运行kafka(一)
  • 单片机嵌入式滤波算法库
  • 从颜料混色到网络安全:DH算法的跨界智慧
  • Java实现桶排序算法
  • 【Git】【commit】查看未推送的提交查看指定commit的修改内容合并不连续的commit
  • 【Ubuntu】安裝向日葵远程控制
  • 可观测性方案怎么选?SelectDB vs Elasticsearch vs ClickHouse
  • [逆向工程]什么是DLL重定向(十九)
  • 基于Stable Diffusion XL模型进行文本生成图像的训练
  • 《社交应用架构生存战:React Native与Flutter的部署容灾决胜法则》
  • k8s(11) — 探针和钩子
  • SpringBoot学生操行评分系统源码设计开发
  • C++函数传值与传引用对比分析