新闻中心
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 操作(尤其是在循环内部)都会导致大量的性能开销,包括重复的数据复制、内存重新分配和索引重建。对于包含数千甚至数万行以上的数据集,这种方法很快就会变得不可接受。
基于VC与Matlab的混合编程实现图像的三维显示 WORD版
本文档主要讲述的是基于VC与Matlab的混合编程实现图像的三维显示;介绍了VC++与Matlab混合编程的一般实现方法,并实现对二维影像图的三维效果显示。 MATLAB既是一种直观、高效的计算机语言,同时又是一个科学计算平台。它为数据分析和数据可视化、算法和应用程序开发提供了最核心的数学和高级图形工具。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
9
查看详情
基于NumPy广播的高效合并策略
为了克服传统方法的性能瓶颈,我们可以利用NumPy的广播(Broadcasting)机制进行矢量化操作。NumPy广播允许对形状不同的数组执行算术运算,其核心思想是自动扩展较小数组的维度,使其与较大数组的维度兼容,从而实现元素级的操作,而无需显式的Python循环。
实现步骤
- 准备数据: 确保参与合并的DataFrame的索引是唯一的。如果DataFrame原有索引不重要,建议在操作前使用 .reset_index(drop=True) 方法重置索引,以避免潜在的索引对齐问题,确保后续 iloc 索引的准确性。
- 转换为NumPy数组并重塑: 将用于比较的时间列转换为NumPy数组。特别是,df1 中的 time_1 和 time_2 列需要被重塑为二维数组(例如 (N, 1) 的形状),而 df2 中的 time_3 列则保持为一维数组((M,) 的形状)。这种形状差异是实现广播的关键。
- 执行广播比较: 利用NumPy的比较运算符(, >=)对重塑后的NumPy数组执行矢量化比较。这将生成一个布尔矩阵,其维度为 (N, M),其中 N 是 df1 的行数,M 是 df2 的行数。矩阵中的每个元素 [i, j] 表示 df1 的第 i 行的时间区间是否包含 df2 的第 j 行的时间点。
- 提取匹配索引: 使用布尔矩阵的 .nonzero() 方法。此方法会返回两个一维NumPy数组 x 和 y,分别包含所有 True 值元素的行索引和列索引。x 中的每个值对应 df1 中匹配的行位置,y 中的每个值对应 df2 中匹配的行位置。
- 合并结果: 最后,利用 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(['2025-10-01 04:02:00', '2025-10-01 04:03:00', '2025-10-01 09:00:00']),
'time_2': pd.to_datetime(['2025-10-01 08:29:00', '2025-10-01 08:49:00', '2025-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([
'2025-10-01 06:21:13.238024',
'2025-10-01 06:47:19.796628',
'2025-10-01 07:37:06.438740',
'2025-10-01 08:16:16.995256',
'2025-10-01 08:33:53.081095',
'2025-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 2025-10-01 04:02:00 2025-10-01 08:29:00 -245.67
1 2025-10-01 04:03:00 2025-10-01 08:49:00 -1772.95
2 2025-10-01 09:00:00 2025-10-01 10:00:00 100.00
DataFrame 2:
time_3 dummy_data_2
0 2025-10-01 以上就是Pandas高效实现基于时间范围的DataFrame合并教程的详细内容,更多请关注其它相关文章!
# 矢量化
# 3g网站建设
# 西安网站建设客服电话
# 东莞营销seo报价
# seo怎么编写
# 综合网站优化的现状
# 阿信抖音seo搜索不到
# seo关键词排名甄选16火星
# 冯耀宗seo
# 邯郸口碑营销seo优化公司
# 怎么做营销号推广赚钱呢
# 多线程
# python
# 这将
# 转换为
# 重启
# 区间内
# 迭代
# 布尔
# 运算符
# 落在
# 性能瓶颈
# app
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Win11怎么开启高性能模式_Windows 11电源计划优化设置
Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】
Sublime Text怎么设置垂直标尺_Sublime配置Rulers规范代码长度
Python多线程中正确使用sigwait处理SIGALRM信号
浏览器打开即用 美图秀秀网页版入口
PostgreSQL海量数据高效导入策略:Python与Django实践指南
黑猫投诉统一入口官网 消费者权益保护投诉平台
单12V-2×6实现为RTX 5090供电750W!甚至都没敢跑分
J*aScript中向JSON对象添加新属性的正确姿势
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
优化Log4j2控制台输出性能:解决异步日志瓶颈
Golang如何通过reflect获取匿名字段方法_Golang reflect匿名字段方法访问技巧
抖音极速版最新版本 抖音极速版官方下载地址
Discord Slash 命令响应超时问题的异步解决方案
理解J*aScript Promise的微任务队列与执行顺序
单射、满射与双射的关系 一文理清所有逻辑
微信客户端如何收红包_微信客户端接收红包使用教程
不同用户不同价格! 索尼开启账户个性化定价测试
如何更改在 Excel 中打开超链接时的默认浏览器
蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源
漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址
j*a toString()的覆盖
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构
QQ邮箱登录官网首页 腾讯QQ邮箱网页入口
响应式图片在网页设计中的正确实现方法
QQ邮箱官方邮箱登录入口 QQ邮箱网页版快速访问
一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰
漫蛙漫画官方首页 漫蛙2漫画在线阅读入口
神庙逃亡小游戏在线玩 神庙逃亡小游戏入口
msn官网入口地址手机版 msn官方网站手机最新链接
文心一言怎样用批量生成做多版文案_文心一言用批量生成做多版文案【批量创作】
Python大型XML文件高效流式解析教程
TikTok网页版直接登录 TikTok网页端官方平台入口
2025-2030年全球乘用车销量预测:新能源成增长主力
Yandex免登录网页版地址 Yandex搜索引擎官方访问入口
如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】
HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制
Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】
KFC游戏互动怎么赢取优惠券_KFC线上游戏活动参与与优惠代码赢取教程
J*a递归快速排序中静态变量的状态管理与陷阱
C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入
Archive of Our Own官网直达 AO3最新可用地址一览
包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接
Excel Power Pivot如何处理XML数据源 构建高级数据模型
Fabric Mod开发:在1.19.3+版本中正确添加自定义物品并管理物品组
AO3中文官网链接_AO3网页版稳定镜像站
Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
钉钉视频会议声音异常如何处理 钉钉会议音频修复技巧


2025-12-08
浏览次数:次
返回列表
df2_processed.iloc[y].reset_index(drop=True), # 重置索引以避免重复索引
],
axis=1,
)
print("\n合并结果:")
print(result_df)