0

0

Pandas 中高效实现时间区间匹配并添加新列的完整教程

花韻仙語

花韻仙語

发布时间:2026-02-08 09:16:12

|

158人浏览过

|

来源于php中文网

原创

Pandas 中高效实现时间区间匹配并添加新列的完整教程

本文介绍如何使用 pd.merge_asof() 高效完成两个 dataframe 的“按分组 + 时间区间内匹配”操作,避免低效嵌套循环,在数十万行数据下将耗时从 10 分钟降至毫秒级。

在数据分析中,常需将事件时间(如设备触发时刻)映射到其所属的时间窗口(如产线作业班次、设备维护周期),并携带对应属性(如工单编号、状态值、测量值等)。本例中,df1 包含按 LOT 分组的事件记录(含 EVENT_TIME),df2 提供每个 LOT 下多个时间窗口(IN_TIME → OUT_TIME)及其关联值 VALUE;目标是为 df1 每一行匹配同一 LOT 下且满足 IN_TIME ≤ EVENT_TIME ≤ OUT_TIME 的 VALUE,生成新列 DATA。

直接使用双重 for 循环(如原问题所示)时间复杂度为 O(n×m),面对 10 万+ 行数据极易超时。Pandas 提供了专为此类场景优化的 merge_asof() —— 它基于排序合并(sort-merge join),支持按键分组、左表时间列与右表时间列的最近向下匹配(nearest backward join),再辅以条件过滤,即可精准实现“区间内匹配”。

✅ 正确步骤与代码实现

首先确保所有时间列已转为 datetime64 类型(merge_asof 强制要求):

import pandas as pd

# 构造示例数据
df1 = pd.DataFrame({
    'LOT': ['A', 'A', 'A', 'A', 'A', 'A'],
    'SLOT': [1, 2, 3, 4, 5, 6],
    'EVENT_TIME': ['2024-01-20 13:30', '2024-01-20 13:36',
                   '2024-01-21 14:28', '2024-01-21 14:30',
                   '2024-01-21 14:32', '2024-01-21 14:34']
})

df2 = pd.DataFrame({
    'LOT': ['A', 'A'],
    'IN_TIME': ['2024-01-20 13:20', '2024-01-21 14:25'],
    'OUT_TIME': ['2024-01-20 13:40', '2024-01-21 14:50'],
    'VALUE': [13, 15]
})

# ✅ 关键:统一转为 datetime
df1['EVENT_TIME'] = pd.to_datetime(df1['EVENT_TIME'])
df2['IN_TIME'] = pd.to_datetime(df2['IN_TIME'])
df2['OUT_TIME'] = pd.to_datetime(df2['OUT_TIME'])

接着使用 merge_asof 实现高效匹配:

# Step 1: merge_asof — 按 LOT 分组,对 EVENT_TIME 在 IN_TIME 上做「向后最近匹配」
# 注意:df2 必须按 by + right_on 排序(merge_asof 自动要求,此处已满足)
result = pd.merge_asof(
    df1.sort_values('EVENT_TIME'),      # 左表必须按 left_on 列升序排序
    df2.sort_values('IN_TIME'),         # 右表必须按 right_on 列升序排序
    by='LOT',                           # 分组键(确保只在相同 LOT 内匹配)
    left_on='EVENT_TIME',               # 左表时间列
    right_on='IN_TIME',                 # 右表起始时间列(作为匹配锚点)
    allow_exact_matches=True,           # 允许 EVENT_TIME == IN_TIME(必需)
    direction='backward'                # 默认行为:取 ≤ EVENT_TIME 的最大 IN_TIME(即最近前一个窗口起点)
)

# Step 2: 过滤掉超出 OUT_TIME 的误匹配(merge_asof 只保证 IN_TIME ≤ EVENT_TIME,不检查上限)
result = result.assign(DATA=lambda x: x['VALUE'].where(x['EVENT_TIME'] <= x['OUT_TIME']))

# Step 3: 清理冗余列,重命名/整理输出
result = result.drop(columns=['IN_TIME', 'OUT_TIME', 'VALUE']).rename(columns={'DATA': 'DATA'})

最终 result 即为目标结构:

LOT SLOT EVENT_TIME DATA
A 1 2024-01-20 13:30:00 13.0
A 2 2024-01-20 13:36:00 13.0
A 3 2024-01-21 14:28:00 15.0
A 4 2024-01-21 14:30:00 15.0
A 5 2024-01-21 14:32:00 15.0
A 6 2024-01-21 14:34:00 15.0
? 为什么用 merge_asof 而非 merge 或 apply? merge 无法直接表达“时间在区间内”的条件(需笛卡尔积 + 布尔索引,O(n×m) 空间爆炸); apply + lambda 本质仍是逐行 Python 循环,无向量化加速; merge_asof 是 Pandas 底层 C 实现的排序合并,复杂度接近 O(n + m),百万级数据通常在 100ms 内完成。

⚠️ 注意事项与最佳实践

  • 排序强制要求:merge_asof 要求左表按 left_on、右表按 right_on 严格升序排列,否则结果不可靠。务必先 .sort_values() 并重置索引(或使用 ignore_index=True)。
  • 区间方向敏感:direction='backward' 匹配 IN_TIME ≤ EVENT_TIME 的最大值;若窗口定义为 (start, end] 或需向上取整,请结合 tolerance 或预处理时间边界。
  • 缺失值处理:未匹配到任何窗口的行,VALUE 将为 NaN,where() 后仍为 NaN —— 符合业务语义(事件不在任何有效窗口内)。
  • 多匹配冲突:若一个 EVENT_TIME 落入多个重叠窗口,merge_asof 仅返回 IN_TIME 最大的那一个(因 backward 取最近)。如需全部匹配结果,请改用 pd.IntervalIndex + loc(适用于中小规模 df2)。
  • 性能验证建议:对真实大数据集,可添加 %%time 魔法命令对比 merge_asof 与原 for 循环耗时,典型提升达 1000× 以上。

掌握 merge_asof 的区间匹配模式,不仅能解决本例的 DATA 列注入问题,还可扩展应用于金融行情快照绑定、IoT 传感器事件归因、日志会话分析等高频场景——关键在于将“范围条件”拆解为“有序锚点匹配 + 边界校验”两步,兼顾效率与准确性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

73

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

3

2026.01.31

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

211

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

191

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

传感器故障解决方法
传感器故障解决方法

传感器故障排除指南:识别故障症状(如误读或错误代码)。检查电源和连接(确保连接牢固,无损坏)。校准传感器(遵循制造商说明)。诊断内部故障(目视检查、信号测试、环境影响评估)。更换传感器(选择相同规格,遵循安装说明)。验证修复(检查信号准确性,监测异常行为)。

477

2024.06.04

数据分析的方法
数据分析的方法

数据分析的方法有:对比分析法,分组分析法,预测分析法,漏斗分析法,AB测试分析法,象限分析法,公式拆解法,可行域分析法,二八分析法,假设性分析法。php中文网为大家带来了数据分析的相关知识、以及相关文章等内容。

479

2023.07.04

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

39

2026.02.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号