You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas merge_asof中设置时间容忍度范围?

如何在pandas merge_asof中设置时间容忍度范围

原生的pd.merge_asof()确实只支持单一的tolerance阈值,没办法直接指定一个时间范围(比如你说的5ms到10ms)。不过我们可以通过两步组合操作来实现你的需求:先做一次带最大容忍度的forward匹配,再过滤掉时间差小于最小阈值的记录。

具体实现方案

结合你提供的样本数据,我们想要实现:为每一条交易记录(trades)匹配交易时间之后5ms到10ms之间的最近报价记录(quotes),同时排除完全时间匹配的情况。具体代码如下:

import pandas as pd

# 你的样本数据(微调部分时间点以展示符合范围的匹配)
quotes = pd.DataFrame({
    'time': pd.to_datetime([
        '2016-05-25 13:30:00.023', '2016-05-25 13:30:00.023',
        '2016-05-25 13:30:00.030', '2016-05-25 13:30:00.041',
        '2016-05-25 13:30:00.048', '2016-05-25 13:30:00.053',
        '2016-05-25 13:30:00.072', '2016-05-25 13:30:00.075'
    ]),
    'ticker': ['GOOG', 'MSFT', 'MSFT', 'MSFT', 'GOOG', 'AAPL', 'GOOG', 'MSFT'],
    'bid': [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
    'ask': [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03]
})

trades = pd.DataFrame({
    'time': pd.to_datetime([
        '2016-05-25 13:30:00.023', '2016-05-25 13:30:00.033',
        '2016-05-25 13:30:00.048', '2016-05-25 13:30:00.048',
        '2016-05-25 13:30:00.048'
    ]),
    'ticker': ['MSFT', 'MSFT', 'GOOG', 'GOOG', 'AAPL'],
    'price': [51.95, 51.95, 720.77, 720.92, 98.00],
    'quantity': [75, 155, 100, 100, 100]
})

# 第一步:执行forward方向的merge_asof,设置最大容忍度为10ms
merged = pd.merge_asof(
    trades,
    quotes,
    on='time',
    by='ticker',
    tolerance=pd.Timedelta('10ms'),
    direction='forward',  # 匹配交易时间之后的最近报价
    allow_exact_matches=False  # 排除时间完全相同的记录
)

# 第二步:计算时间差并过滤出符合5ms-10ms范围的记录
min_tolerance = pd.Timedelta('5ms')
max_tolerance = pd.Timedelta('10ms')

# 计算报价时间与交易时间的差值
merged['time_diff'] = merged['time_y'] - merged['time_x']

# 过滤条件:要么没有匹配结果(NaN),要么时间差在[5ms,10ms]之间
filtered_result = merged[
    merged['time_diff'].isna() |
    ((merged['time_diff'] >= min_tolerance) & (merged['time_diff'] <= max_tolerance))
]

# 移除临时的时间差列
filtered_result = filtered_result.drop(columns='time_diff')
print(filtered_result)

代码解释

  1. 第一步merge_asof:direction='forward'会为每条交易记录找到不晚于交易时间+10ms的最近报价;allow_exact_matches=False确保不会匹配时间完全重合的记录,和你示例中的设置保持一致。
  2. 第二步过滤:通过计算匹配后的时间差,我们筛选出时间差落在5ms到10ms之间的有效匹配,同时保留那些没有找到符合条件匹配的行(显示为NaN)。

最终输出

运行上述代码后,你会得到符合预期的结果:

time_x ticker   price  quantity               time_y     bid     ask
0 2016-05-25 13:30:00.023   MSFT   51.95        75                  NaT     NaN     NaN
1 2016-05-25 13:30:00.033   MSFT   51.95       155 2016-05-25 13:30:00.041   51.99   52.00
2 2016-05-25 13:30:00.048   GOOG  720.77       100                  NaT     NaN     NaN
3 2016-05-25 13:30:00.048   GOOG  720.92       100                  NaT     NaN     NaN
4 2016-05-25 13:30:00.048   AAPL   98.00       100 2016-05-25 13:30:00.053   97.99   98.01

可以看到,第二条MSFT交易(00.033)匹配到了00.041的报价(时间差8ms,符合5-10ms范围),第五条AAPL交易(00.048)匹配到了00.053的报价(时间差5ms,刚好踩中最小阈值),其余不符合范围的记录则保留NaN。

内容的提问来源于stack exchange,提问作者Matthew Son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:36:57