新闻中心

Pandas DataFrame高效查找:定位满足条件的最近历史索引日期

2025-11-05
浏览次数:
返回列表

pandas dataframe高效查找:定位满足条件的最近历史索引日期

本教程探讨如何在Pandas DataFrame中高效地为每一行查找满足特定条件(如`lower >= upper`)的最近历史行索引(日期)。针对传统`df.apply`方法的低效性,文章重点介绍并演示了如何利用Python内置的`bisect`模块实现高性能查找,并简要提及其他优化尝试,最终旨在提供一种处理此类依赖历史状态问题的最佳实践。

在数据分析和处理中,我们经常会遇到需要基于当前行之前的历史数据来计算新列的场景。一个典型的例子是,对于DataFrame中的每一行,我们需要找到一个特定条件(例如,某一列的值大于或等于另一列的值)在之前行中最后一次满足时的索引(通常是日期时间索引)。然而,直接使用Pandas的apply方法进行逐行操作,尤其是在大数据集上,效率会非常低下。

初始方法及性能瓶颈

考虑以下场景:我们有一个包含lower和upper两列的DataFrame,并以日期作为索引。目标是创建一个新列prev,其中包含满足 lower >= upper 条件的最近历史行的日期索引。

import pandas as pd
import numpy as np

# 示例DataFrame
data = {'lower': [7, 1, 6, 1, 1, 1, 1, 11, 1, 1],
        'upper': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}
df = pd.DataFrame(data=data)
df['DATE'] = pd.date_range('2025-01-01', periods=len(data['lower']))
df['DATE'] = pd.to_datetime(df['DATE'])
df.set_index('DATE', inplace=True)

# 使用 df.apply 的原始方法
def get_most_recent_index(row):
    # 查找当前行之前的所有行
    previous_indices = df.loc[:row.name - pd.Timedelta(minutes=1)]  
    # 筛选满足条件的行,并获取最大的索引(即最近的日期)
    recent_index = previous_indices[previous_indices['lower'] >= row['upper']].index.max()
    return recent_index

df['prev'] = df.apply(get_most_recent_index, axis=1) 
print(df)

上述代码中的get_most_recent_index函数通过df.loc对DataFrame进行切片,然后进行条件筛选,最后获取最大索引。这种方法的问题在于:

刺鸟创客 刺鸟创客

一款专业高效稳定的AI内容创作平台

刺鸟创客 110 查看详情 刺鸟创客
  1. 逐行迭代: df.apply(axis=1)本质上是Python级别的循环,效率远低于Pandas或NumPy的向量化操作。
  2. 重复切片与筛选: 每一行都会对DataFrame进行一次切片和条件筛选,对于大型DataFrame,这会导致大量的重复计算和内存操作。 在一个包含100,000行的DataFrame上,这种方法的执行时间可能长达数分钟,这在实际应用中是难以接受的。

采用 bisect 模块实现高效查找

为了显著提升性能,我们可以利用Python内置的bisect模块。bisect模块提供了二分查找算法,可以在已排序的序列中快速定位元素。虽然这个问题并非完全向量化,但通过巧妙地结合bisect和字典来维护历史状态,可以实现准线性时间复杂度的解决方案。

核心思想是:

  1. 维护一个已排序的、不重复的lower值列表 (uniq_lower)。
  2. 维护一个字典last_seen,记录每个lower值最后一次出现的日期。
  3. 对于DataFrame中的每一行,我们需要找到所有满足 l >= current_upper 的 l 值,并从 last_seen 中找出这些 l 值对应的最大日期。

以下是使用bisect模块的优化实现:

from bisect import bisect_left

def get_prev_bs(lower_series, upper_series, date_index):
    # 获取所有不重复的 lower 值并排序
    uniq_lower = sorted(set(lower_series))
    # 存储每个 lower 值最后一次出现的日期
    last_seen = {}

    # 迭代 DataFrame 的每一行
    for l, u, d in zip(lower_series, upper_series, date_index):
        # 使用 bisect_left 找到第一个大于或等于当前 upper 值的 lower 值的索引
        # 这意味着 uniq_lower[idx:] 包含了所有 >= u 的 lower 值
        idx = bisect_left(uniq_lower, u)

        max_date = None
        # 遍历所有满足条件的 lower 值
        for lv in uniq_lower[idx:]:
            if lv in last_seen:
                # 如果该 lower 值在历史中出现过
                if max_date is None:
                    max_date =

以上就是Pandas DataFrame高效查找:定位满足条件的最近历史索引日期的详细内容,更多请关注其它相关文章!


# 大数据  # app  # 性能瓶颈  # 如何实现  # 迭代  # 是在  # 这种方法  # python  # 上海家具网站建设语言  # 专注网站建设16年  # 罗山seo网络推广团队  # saas网站搜索优化技术方案  # 蚂蚁链 seo  # 七夕节餐厅营销推广文案  # 网站微博的推广怎么推  # 工作室网站建设行情  # 威县网站建设是什么工作  # 网站seo营销中心  # 中文网  # 相关文章  # 这个问题  # 执行时间  # 遍历  # 第一个 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Win10双系统截图高效法 截屏快捷键速记【技巧】  Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】  顺丰快件物流信息 官方网站查询入口  动漫共和国防屏蔽稳定域名-动漫共和国官方正版直达通道  React Router v6 教程:构建认证保护的私有路由与重定向策略  mc.js官网登录入口 mc.js官方登录入口最新版  12306选座怎么选到商务座_12306商务座选择与配置说明  Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧  C++如何实现单例模式_C++设计模式之线程安全的单例写法  163邮箱注册官网 免费申请163个人邮箱  在Go Martini框架中高效服务动态生成图像的实践指南  凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法  PHP高效扁平化嵌套数组:使用array_merge与数组解包操作符  必由学官方网站入口 必由学学生教师共用登录通道  如何使 Jest 模拟函数默认抛出错误以提高测试效率  wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录  Golang如何使用buffered channel提高性能_Golang buffered channel优化技巧  虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画  Discord Slash 命令响应超时问题的异步解决方案  如何优雅地解决Livewire文件上传难题?SpatieLivewireFilepond让一切变得简单  vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法  如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式  极兔快递快件信息查询系统 极兔快递官网运单号追踪  C++如何比较两个字符串_C++ string compare函数与操作符对比  HTML长属性值处理:表单action路径优化与代码规范应对  c++如何实现一个简单的ECS框架_c++数据驱动设计与游戏开发  Go语言中JSON数据解码与字段访问指南  Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏  c++20的std::jthread是什么_c++可中断线程与RAII式管理  J*aScript中如何高效提取对象指定属性  如何在 Windows 11 中启动游戏手柄设置  Win11怎么查看显卡显存 Win11显示适配器属性及专用视频内存查询  python3时间如何用calendar输出?  解决 MongoDB 聚合查询中对象数组 _id 匹配问题  怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】  实现全屏滚动与导航点:专业教程  CSS Box Model与弹性按钮:维持布局稳定的动画实践  新手怎么开始学化妆 零基础化妆入门教程  J*a最大堆Heapify方法修复:索引计算与边界条件深度解析  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  C++如何实现一个装饰器模式_C++设计模式之动态地给对象添加额外职责  fishbowl官网免费版 fishbowl养鱼网站入口  Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法  如何将HTML表格多行数据保存到Google Sheet  CSS布局:解决全屏元素100%尺寸与外边距导致的页面溢出问题  使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性  抖音从哪里进入网页版_抖音官方入口链接  Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】  2026春节假期票务安排_2026春节放假购票指南 

搜索