新闻中心

使用 Pandas 实现条件性累积最小值(cummin)重置的技巧

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

使用 pandas 实现条件性累积最小值(cummin)重置的技巧

本文深入探讨了在 Pandas DataFrame 中,如何创建一个新列 c,该列的值基于列 b 的累积最小值 (cummin()),但其计算过程会根据列 a 和 c 的前一个值的特定条件进行动态重置。我们将通过一个复杂的布尔掩码和分组操作的组合,展示一个高效且完全向量化的解决方案,以应对这种递归依赖的计算挑战。

在数据分析和处理中,我们经常需要根据复杂的业务逻辑创建新的特征列。其中一种常见的需求是计算累积最小值 (cummin()),但更具挑战性的是,当这个累积最小值需要在特定条件下“重置”并重新开始计算时。本教程将详细介绍如何使用 Pandas 库,以向量化的方式解决一个具体的问题:创建一个新列 c,它基于列 b 的累积最小值,但在满足 df.a.shift(1) > df.c.shift(1) 这一条件时,c 的值变为当前 b 的值,并且 cummin() 的计算从该点重新开始。

问题描述与初始数据

假设我们有一个 Pandas DataFrame,包含两列 a 和 b:

import pandas as pd

df = pd.DataFrame(
    {
        'a': [98, 97, 100, 135, 103, 100, 105, 109, 130],
        'b': [100, 103, 101, 105, 110, 120, 101, 150, 160]
    }
)

print("原始 DataFrame:")
print(df)

我们的目标是创建列 c,其计算规则如下:

  1. 初始时,c 的值是 b 的累积最小值 (df.b.cummin())。
  2. 当满足条件 df.a.shift(1) > df.c.shift(1) 时,当前行的 c 值应等于当前行的 b 值。
  3. 更重要的是,一旦条件满足,cummin() 的计算将从当前行开始“重置”,即后续行的 c 值将是当前行 b 值开始的累积最小值。

这是一个具有挑战性的问题,因为它涉及到对 c 列的递归依赖(c 的计算依赖于其自身的先前值),这使得简单的向量化操作变得困难。

期望的输出 df 如下:

     a    b    c
0   98  100  100
1   97  103  100
2  100  101  100
3  135  105  100
4  103  110  110  # 条件触发,c=b,cummin重置
5  100  120  110  # 从上一行b=110开始的cummin
6  105  101  101  # 从上一行b=110开始的cummin
7  109  150  150  # 条件触发,c=b,cummin重置
8  130  160  150  # 从上一行b=150开始的cummin

向量化解决方案

为了解决这种带有条件重置的累积计算问题,我们可以利用 Pandas 的 groupby 和布尔掩码 (mask, where) 功能。以下是实现所需逻辑的向量化代码:

m1 = df["b"].le(df["a"].shift())
cm = df["b"].groupby(m1.cumsum()).cummin()
m2 = (df["b"].le(cm) | df["a"].shift().le(cm.shift()))
df["c"] = cm.where(m2, df["b"].mask(m2).cummin())

print("\n生成列 'c' 后的 DataFrame:")
print(df)

解决方案详解

这个解决方案通过引入几个中间布尔掩码和分组累积操作,巧妙地避免了递归计算,实现了完全的向量化。让我们逐步解析每个部分的含义:

PictoGraphic PictoGraphic

AI驱动的矢量插图库和插图生成平台

PictoGraphic 133 查看详情 PictoGraphic
  1. m1 = df["b"].le(df["a"].shift())

    • 这一步创建了一个布尔序列 m1,用于标识 b 的当前值是否小于或等于 a 的前一个值。
    • df["a"].shift() 将 a 列向下移动一位,使得当前行可以与前一行的 a 值进行比较。
    • le() 是 "less than or equal to" 的缩写。
    • m1 的作用是识别潜在的“重置点”或“新组的开始”。当 b 相对前一个 a 变得足够小(或相等)时,这可能意味着一个新的累积最小值序列的开始。

    示例 m1 值的生成:

    a_s (a.shift())  b    b <= a_s  -> m1
    NaN              100  False
    98.0             103  False
    97.0             101  False
    100.0            105  False
    135.0            110  True   # b(110) <= a_s(135)
    103.0            120  False
    100.0            101  False
    105.0            150  False
    109.0            160  False
  2. cm = df["b"].groupby(m1.cumsum()).cummin()

    • m1.cumsum():这一步是关键。m1 中的 True 值会被视为 1,False 视为 0。cumsum() 会计算这些 0 和 1 的累积和。当 m1 遇到一个 True 时,累积和会增加 1,从而创建一个新的组 ID。
    • 例如,如果 m1 是 [F, F, T, F, T],那么 m1.cumsum() 将是 [0, 0, 1, 1, 2]。
    • df["b"].groupby(m1.cumsum()):根据 m1.cumsum() 生成的组 ID 对 b 列进行分组。
    • .cummin():在每个分组内部独立地计算 b 的累积最小值。这有效地实现了“条件性重置”的累积最小值,即每当 m1 为 True 时,累积最小值就会重新开始计算。

    示例 cm 值的生成:

    m1        m1.cumsum()  b       cm (分组cummin)
    False     0            100     100
    False     0            103     100
    False     0            101     100
    False     0            105     100
    True      1            110     110
    False     1            120     110
    False     1            101     101
    False     1            150     101
    False     1            160     101
  3. m2 = (df["b"].le(cm) | df["a"].shift().le(cm.shift()))

    • m2 是一个最终的布尔掩码,用于决定 c 列的每个值应该从 cm 中取,还是从一个独立的、基于 b 的 cummin 中取。
    • 它由两个条件通过逻辑或 (|) 组合而成:
      • df["b"].le(cm):当前 b 值是否小于或等于 cm 值。如果为真,意味着 b 仍在当前 cm 序列的范围内。
      • df["a"].shift().le(cm.shift()):a 的前一个值是否小于或等于 cm 的前一个值。如果为真,表示前一个状态仍然符合累积最小值的逻辑。
    • 当 m2 为 True 时,表示 cm 中的值是有效的,可以作为 c 的值。
    • 当 m2 为 False 时,表示 cm 中的值不再有效(例如,当前 b 值远大于 cm,或者前一个 a 值相对于前一个 cm 值过大),此时需要启动一个新的 cummin 序列,其起始值就是当前的 b。

    示例 m2 值的生成:

    b    cm   b<=cm  a_s  cm_s  a_s<=cm_s  m2 (b<=cm | a_s<=cm_s)
    100  100  True   NaN  NaN   False      True
    103  100  False  98   100   True       True
    101  100  False  97   100   True       True
    105  100  False  100  100   True       True
    110  110  True   135  100   False      True
    120  110  False  103  110   True       True
    101  101  True   100  110   True       True
    150  101  False  105  101   False      False  # b(150)>cm(101) 且 a_s(105)>cm_s(101)
    160  101  False  109  101   False      False  # b(160)>cm(101) 且 a_s(109)>cm_s(101)
  4. df["c"] = cm.where(m2, df["b"].mask(m2).cummin())

    • 这是最终 c 列的构造步骤。
    • cm.where(m2, ...):where 函数根据布尔条件 m2 来选择值。
      • 如果 m2 为 True,则 c 的值取自 cm。
      • 如果 m2 为 False,则 c 的值取自 where 函数的第二个参数。
    • df["b"].mask(m2):

以上就是使用 Pandas 实现条件性累积最小值(cummin)重置的技巧的详细内容,更多请关注其它相关文章!


# 短视频seo公司  # 武汉建设网站哪个好  # 网站相关推广软文  # 马鞍山全网营销推广口碑  # 东莞优化网站推广  # 网站标准版和网站推广版  # 随州低成本网站优化公司  # 中山电器建材网站seo优化  # 高端民宿营销推广文案  # 新疆网站建设费用明细  # 最小值  # 这是  # 是一个  # 中取  # 将是  # 创建一个  # 掩码  # 的是  # 布尔  # 递归 


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


相关推荐: 蛙漫安全无毒 官方认证的绿色入口  c++20的std::jthread是什么_c++可中断线程与RAII式管理  网易大神账号申诉需要多久_网易大神账号申诉流程说明  菜鸟取件码是什么怎么查 最全查询渠道汇总  支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡  夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案  Mac怎么锁定备忘录_Mac备忘录加密设置教程  C++ map遍历方法大全_C++ map迭代器使用总结  CSS子选择器:如何区分并样式化嵌套列表的子层级  mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析  mysql备份恢复性能优化_mysql备份恢复性能优化方法  AO3网页版最新入口合集 Archive of Our Own在线访问指南  Go语言中JSON数据解析与字段访问教程  向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程  React Router 嵌套组件中 URL 重定向问题的解决方案  QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口  利用Bokeh CustomJS动态控制DataTable列可见性  2026春节假期时间安排 2026春节假日查询  Win10文件资源管理器“此电脑”分组怎么关 Win10恢复经典视图【技巧】  c++如何使用Meson构建系统_c++比CMake更快的构建工具  C++如何实现线程池_C++11手动实现一个简单的固定大小线程池  汽水音乐网页版使用入口_汽水音乐电脑版播放指南  如何使用spryker/configurable-bundles-products-resource-relationship模块解决复杂产品捆绑关系难题  HTML元素状态管理:根据DIV内容动态启用/禁用按钮  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  c++ 获取系统当前时间 c++时间戳获取方法  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  微信网页版扫码登录入口 微信网页版二维码登录入口  Windows 11怎么彻底关闭定位_Windows 11服务中禁用Geolocation  生成rdflib自定义SPARQL函数:参数匹配与实践指南  漫蛙漫画官方首页 漫蛙2漫画在线阅读入口  如何创建独立于主系统的J*a运行环境_隔离式环境搭建策略  Golang并发任务中错误如何聚合_Golang goroutine error收集方式  React/Next.js中实现列表项的动态选择与移动  Golang如何使用new_Go new分配内存机制讲解  LINUX怎么设置定时任务_LINUX crontab配置教程  高德地图沿途添加点失败如何解决 高德多点规划方法  PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误  Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值  虚幻5科幻题材ARPG大作遭取消!本是《奇异人生》厂商新作  必由学官方登录入口 必由学教师学生账号快速访问  Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置  QQ网页版官方账号入口 QQ网页版网页版登录指南  Centos/Linux 系统下安装 composer 的完整步骤  c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架  在Typer应用中优雅地处理和重组任意命令行参数  C++的std::mdspan是什么_C++23中用于操作多维数组的非拥有视图  解决Python单元测试中Mock异常方法调用计数为零的问题  AO3官方可用镜像 Archive of Our Own网页版最新入口  c++中的std::basic_string的SSO优化_c++短字符串优化深度解析 

搜索