讲师中心 微信公众号
AI工具推荐 视频效率加速

Pandas高效实现基于时间范围的DataFrame合并教程

轻辰大大_7452

轻辰大大_7452

发布时间:2025-12-08 15:24:55

|

707人浏览过

|

来源于php中文网

原创

Pandas高效实现基于时间范围的DataFrame合并教程

本教程深入探讨如何在pandas中高效合并两个dataframe,其中一个dataframe的某一时间列需落在另一个dataframe的两个时间列所定义的区间内。我们将摒弃低效的迭代方法,转而采用numpy广播机制,通过矢量化操作显著提升合并大型数据集的性能,并讨论相关的内存管理考量。

在数据分析和处理中,我们经常会遇到需要根据非精确条件(例如时间范围)合并两个DataFrame的情况。一个典型的场景是,我们有一个DataFrame df1,其中包含时间区间的起始 (time_1) 和结束 (time_2),以及另一个DataFrame df2,其中包含单个时间点 (time_3)。我们的目标是,将 df2 中 time_3 落在 df1 任意行的 [time_1, time_2] 区间内的记录与 df1 中对应的行进行合并,并且 df1 的行可能需要被复制多次。

传统方法的局限性

面对这类合并需求,许多开发者可能会自然而然地采用迭代方式。例如,通过嵌套循环遍历 df1 的每一行,然后对 df2 的所有行进行条件筛选,最后使用 pd.concat 或 df.append 将结果逐一拼接。

# 伪代码示例,展示传统方法的思路,实际执行会非常慢
# output_df = pd.DataFrame()
# for i in df1.index:
#     # 筛选 df2 中 time_3 落在 df1.loc[i] 区间内的行
#     matching_df2_rows = df2[(df2['time_3'] >= df1.loc[i]['time_1']) & \
#                             (df2['time_3'] < df1.loc[i]['time_2'])]
#     for _, row_df2 in matching_df2_rows.iterrows():
#         output_df = output_df.append(pd.concat([df1.loc[i], row_df2]), ignore_index=True)

这种方法虽然直观,但效率极低。Pandas的 loc 索引、循环迭代以及 append 操作(尤其是在循环内部)都会导致大量的性能开销,包括重复的数据复制、内存重新分配和索引重建。对于包含数千甚至数万行以上的数据集,这种方法很快就会变得不可接受。

python-parallelization
python-parallelization

将顺序 Python 代码转换为并行/并发实现,用于在需要并行化 Python 代码、提升性能时使用。

下载

基于NumPy广播的高效合并策略

为了克服传统方法的性能瓶颈,我们可以利用NumPy的广播(Broadcasting)机制进行矢量化操作。NumPy广播允许对形状不同的数组执行算术运算,其核心思想是自动扩展较小数组的维度,使其与较大数组的维度兼容,从而实现元素级的操作,而无需显式的Python循环。

实现步骤

  1. 准备数据: 确保参与合并的DataFrame的索引是唯一的。如果DataFrame原有索引不重要,建议在操作前使用 .reset_index(drop=True) 方法重置索引,以避免潜在的索引对齐问题,确保后续 iloc 索引的准确性。
  2. 转换为NumPy数组并重塑: 将用于比较的时间列转换为NumPy数组。特别是,df1 中的 time_1 和 time_2 列需要被重塑为二维数组(例如 (N, 1) 的形状),而 df2 中的 time_3 列则保持为一维数组((M,) 的形状)。这种形状差异是实现广播的关键。
  3. 执行广播比较: 利用NumPy的比较运算符(<, <=, >, >=)对重塑后的NumPy数组执行矢量化比较。这将生成一个布尔矩阵,其维度为 (N, M),其中 N 是 df1 的行数,M 是 df2 的行数。矩阵中的每个元素 [i, j] 表示 df1 的第 i 行的时间区间是否包含 df2 的第 j 行的时间点。
  4. 提取匹配索引: 使用布尔矩阵的 .nonzero() 方法。此方法会返回两个一维NumPy数组 x 和 y,分别包含所有 True 值元素的行索引和列索引。x 中的每个值对应 df1 中匹配的行位置,y 中的每个值对应 df2 中匹配的行位置。
  5. 合并结果: 最后,利用 iloc 根据 nonzero() 返回的 x 和 y 索引,从原始(或重置索引后)的 df1 和 df2 中选择相应的行。由于 x 和 y 数组的长度相同,我们可以直接将 df1.iloc[x] 和 df2.iloc[y] 通过 pd.concat 沿列方向合并,生成最终的合并结果DataFrame。

示例代码

import pandas as pd
import numpy as np

# 模拟数据
# DataFrame 1: 包含时间区间 time_1 和 time_2
data1 = {
    'time_1': pd.to_datetime(['2023-10-01 04:02:00', '2023-10-01 04:03:00', '2023-10-01 09:00:00']),
    'time_2': pd.to_datetime(['2023-10-01 08:29:00', '2023-10-01 08:49:00', '2023-10-01 10:00:00']),
    'dummy_data_1': [-245.67, -1772.95, 100.0]
}
df1 = pd.DataFrame(data1)

# DataFrame 2: 包含时间点 time_3
data2 = {
    'time_3': pd.to_datetime([
        '2023-10-01 06:21:13.238024',
        '2023-10-01 06:47:19.796628',
        '2023-10-01 07:37:06.438740',
        '2023-10-01 08:16:16.995256',
        '2023-10-01 08:33:53.081095',
        '2023-10-01 09:30:00.000000' # 此时间点落在df1的第三个区间
    ]),
    'dummy_data_2': [-131.37, -236.28, 5.92, -134.03, -103.73, 50.0]
}
df2 = pd.DataFrame(data2)

print("DataFrame 1:")
print(df1)
print("\nDataFrame 2:")
print(df2)

# --- 高效合并逻辑 ---

# 1. 确保索引是唯一的。如果不需要保留原有索引,建议重置。
#    这将确保iloc[x]和iloc[y]能正确地按位置索引。
df1_processed = df1.reset_index(drop=True)
df2_processed = df2.reset_index(drop=True)

# 2. 准备NumPy数组进行广播
#    将time_1和time_2重塑为(N, 1)的二维数组,t3保持(M,)的一维数组
t1 = df1_processed["time_1"].to_numpy()[:, None]
t2 = df1_processed["time_2"].to_numpy()[:, None]
t3 = df2_processed["time_3"].to_numpy()

# 3. 执行广播比较,生成布尔矩阵
#    这里使用开区间 (time_1 < time_3 < time_2)。
#    如果需要左闭右开区间 [time_1, time_2),条件应为 (t1 <= t3) & (t3 < t2)。
#    如果需要闭区间 [time_1, time_2],条件应为 (t1 <= t3) & (t3 <= t2)。
match_matrix = (t1 < t3) & (t3 < t2)

# 4. 获取匹配的行索引
#    x 对应 df1_processed 的行索引,y 对应 df2_processed 的行索引
x, y = match_matrix.nonzero()

# 5. 合并结果
#    使用iloc根据匹配索引从原始DataFrame中选择行,然后沿列方向合并
result_df = pd.concat(
    [
        df1_processed.iloc[x].reset_index(drop=True), # 重置索引以避免重复索引
        df2_processed.iloc[y].reset_index(drop=True), # 重置索引以避免重复索引
    ],
    axis=1,
)

print("\n合并结果:")
print(result_df)

输出结果示例:

DataFrame 1:
               time_1              time_2  dummy_data_1
0 2023-10-01 04:02:00 2023-10-01 08:29:00       -245.67
1 2023-10-01 04:03:00 2023-10-01 08:49:00      -1772.95
2 2023-10-01 09:00:00 2023-10-01 10:00:00        100.00

DataFrame 2:
                   time_3  dummy_data_2
0 2023-10-01 

热门AI工具

更多
切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

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

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

320

2025.12.04

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

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

252

2026.01.31

Python数据分析与Pandas高级实战
Python数据分析与Pandas高级实战

本专题围绕 Python 数据分析展开,系统讲解 Pandas 的高级用法,包括数据清洗、透视表、时间序列分析以及多表合并与分组操作。通过实战案例,帮助开发者掌握高效处理与分析数据的方法,提高数据处理效率与分析能力。

551

2026.04.13

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6084

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2944

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

1772

2025.10.17

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

598

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1476

2023.11.14

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

80

2026.10.16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn