说明
pd.merge_asof()用于执行基于有序键(通常是时间)的近似匹配合并,类似merge_ordered(),但不会匹配完全相等的键,而是匹配最近的键。常用于事件对齐、信号配对等场景。
语法
pd.merge_asof(
left, # 左侧 DataFrame
right, # 右侧 DataFrame
on=None, # 公共有序键(通常为时间列)
left_on=None, # 左侧键列
right_on=None, # 右侧键列
left_index=False, # 使用左侧索引作为键
right_index=False, # 使用右侧索引作为键
by=None, # 分组列(匹配前先按此列分组)
left_by=None, # 左侧分组列
right_by=None, # 右侧分组列
suffixes=('_x', '_y'), # 重叠列后缀
tolerance=None, # 最大匹配距离
allow_exact_matches=True, # 是否允许精确匹配
direction='backward', # 匹配方向
)参数说明
| 参数 | 说明 | 默认 |
|---|---|---|
on | 两侧共有的有序键(通常是时间) | None |
tolerance | 匹配的最大时间差,超过则不匹配 | None(无限) |
allow_exact_matches | 是否返回完全相等的匹配 | True |
direction | 匹配方向:'backward'、'forward'、'nearest' | 'backward' |
by | 在合并前先按此列分组,组内分别匹配 | None |
direction 匹配方向
说明
控制左侧键与右侧键的匹配方向:
| 方向 | 含义 | 示例 |
|---|---|---|
'backward' | 匹配右侧小于等于左侧键的最近行 | 查询某一时刻之前的最近状态 |
'forward' | 匹配右侧大于等于左侧键的最近行 | 查询某一时刻之后的最近事件 |
'nearest' | 匹配距离最近的行(绝对距离最小) | 通用最近邻匹配 |
基础示例
import pandas as pd
left = pd.DataFrame({
'time': pd.to_datetime(['2026-08-19 10:00', '2026-08-19 10:10', '2026-08-19 10:20']),
'value_l': [1, 2, 3],
})
right = pd.DataFrame({
'time': pd.to_datetime(['2026-08-19 10:05', '2026-08-19 10:15']),
'value_r': [100, 200],
})
# 默认 backward:取右侧 ≤ 左侧键的最近一行
print(pd.merge_asof(left, right, on='time'))
# time value_l value_r
# 0 2026-08-19 10:00:00 1 NaN
# 1 2026-08-19 10:10:00 2 100.0
# 2 2026-08-19 10:20:00 3 200.0direction=‘forward’
print(pd.merge_asof(left, right, on='time', direction='forward'))
# time value_l value_r
# 0 2026-08-19 10:00:00 1 100.0
# 1 2026-08-19 10:10:00 2 200.0
# 2 2026-08-19 10:20:00 3 NaNdirection=‘nearest’
print(pd.merge_asof(left, right, on='time', direction='nearest'))
# time value_l value_r
# 0 2026-08-19 10:00:00 1 100.0
# 1 2026-08-19 10:10:00 2 100.0
# 2 2026-08-19 10:20:00 3 200.0tolerance:限制匹配距离
说明
以
on列的单位为准,限制左右键的最大差值。超过tolerance则不匹配(结果中为 NaN)。
print(pd.merge_asof(left, right, on='time', tolerance=pd.Timedelta('5min')))
# time value_l value_r
# 0 2026-08-19 10:00:00 1 NaN # 10:00 与 10:05 差 5 分钟,tolerance 包含边界 → 应匹配?实际边界行为需测试
# 1 2026-08-19 10:10:00 2 100.0
# 2 2026-08-19 10:20:00 3 200.0
# tolerance 使用数值(如 on 列为整数秒)
l2 = pd.DataFrame({'t': [1, 5], 'v': [10, 20]})
r2 = pd.DataFrame({'t': [3, 7], 'w': [100, 200]})
print(pd.merge_asof(l2, r2, on='t', tolerance=2))
# t v w
# 0 1 10 100.0 # |1-3|=2 ≤ 2
# 1 5 20 200.0 # |5-7|=2 ≤ 2allow_exact_matches
说明
当为
False时,精确相等的键不匹配,只匹配严格大于/小于的最近值。
print(pd.merge_asof(left, right, on='time', allow_exact_matches=False))
# time value_l value_r
# 0 2026-08-19 10:00:00 1 NaN
# 1 2026-08-19 10:10:00 2 NaN # 10:10 与 right 10:15 不够近?需看数据
# 2 2026-08-19 10:20:00 3 200.0by:分组匹配
说明
先按
by列分组,再在组内进行近似匹配,常用于“按标的物 + 按时间”的配对场景。
left = pd.DataFrame({
'symbol': ['A', 'A', 'B', 'B'],
'time': pd.to_datetime(['2026-08-19 10:00', '2026-08-19 10:10',
'2026-08-19 10:00', '2026-08-19 10:10']),
'bid': [1, 2, 3, 4],
})
right = pd.DataFrame({
'symbol': ['A', 'A', 'B', 'B'],
'time': pd.to_datetime(['2026-08-19 10:05', '2026-08-19 10:15',
'2026-08-19 10:05', '2026-08-19 10:15']),
'ask': [100, 200, 300, 400],
})
print(pd.merge_asof(left, right, on='time', by='symbol'))
# symbol time bid ask
# 0 A 2026-08-19 10:00:00 1 NaN
# 1 A 2026-08-19 10:10:00 2 100.0
# 2 B 2026-08-19 10:00:00 3 NaN
# 3 B 2026-08-19 10:10:00 4 300.0🔗 相关链接
- 14.5 merge_ordered() - 有序数据合并
- 14.2 merge() - 精确匹配合并
- index - 时间键的创建与处理