利用Pandas高效创建依赖上一个有效值的条件列

利用Pandas高效创建依赖上一个有效值的条件列

本文详细介绍了如何在Pandas DataFrame中高效地创建新列,使其值根据特定条件和相邻单元格进行填充。核心方法是结合使用Series.where()进行条件性赋值,以及Series.bfill()或Series.ffill()来回填或前向填充缺失值,从而实现复杂的数据依赖逻辑,避免低效的循环操作。

场景描述与挑战

在数据处理中,我们经常需要根据一列的特定条件来创建或修改另一列。更复杂的情况是,当条件不满足时,新列的值需要依赖于其上方或下方的某个有效值。例如,给定一个包含“colonne 1”和“dimension 1”的dataframe,我们的目标是创建一个新列“new”,其规则如下:

如果“Dimension 1”列的值为“Organisation”,则“new”列的对应单元格取“Colonne 1”列的当前值。如果“Dimension 1”列的值不是“Organisation”,则“new”列的对应单元格需要从其下方最近的“Organisation”类型单元格中获取值,并向上填充。

传统的迭代方法(如使用for循环或apply函数)在处理大型DataFrame时效率低下。Pandas提供了更优化的矢量化操作来解决这类问题。

解决方案:结合where()与填充方法

Pandas中的Series.where()方法允许我们根据一个布尔条件选择性地替换Series中的值。当条件为False时,对应位置的值会被替换为NaN(默认),这为后续的填充操作创造了条件。接着,我们可以利用Series.bfill()(backward fill,向后填充)或Series.ffill()(forward fill,向前填充)来处理这些NaN值,实现复杂的依赖填充逻辑。

1. 使用 Series.where() 创建条件性缺失值

首先,我们使用where()方法来初步填充“new”列。如果“Dimension 1”是“Organisation”,则取“Colonne 1”的值;否则,该位置暂时留空(NaN)。

import pandas as pdimport io# 示例数据data = """  Colonne 1   Dimension 10  MTN_LI2      Indicator1  MTN_IRU      Indicator2  MTN_ACE      Indicator3  MTN_IME      Indicator4     RIPP7  Organisation5    CA_SOT     Indicator6    CA_OTI     Indicator7     CNW00  Organisation8     BSNTF  Organisation9     RIPNJ  Organisation"""df = pd.read_csv(io.StringIO(data), sep=r's{2,}', engine='python', skipinitialspace=True)# 步骤1: 使用where()初步创建新列# 如果 df['Dimension 1'] 等于 'Organisation',则取 df['Colonne 1'] 的值,# 否则,该位置为 NaNdf['new_temp'] = df['Colonne 1'].where(df['Dimension 1'].eq('Organisation'))print("--- 步骤1结果 (初步填充,非Organisation为NaN) ---")print(df)

输出 df[‘new_temp’] 将会是:

--- 步骤1结果 (初步填充,非Organisation为NaN) ---  Colonne 1   Dimension 1 new_temp0  MTN_LI2      Indicator      NaN1  MTN_IRU      Indicator      NaN2  MTN_ACE      Indicator      NaN3  MTN_IME      Indicator      NaN4     RIPP7  Organisation    RIPP75    CA_SOT     Indicator      NaN6    CA_OTI     Indicator      NaN7     CNW00  Organisation    CNW008     BSNTF  Organisation    BSNTF9     RIPNJ  Organisation    RIPNJ

2. 使用 Series.bfill() 向后填充(向下查找,向上填充)

为了满足“如果不是’Organisation’,则取其下方最近的’Organisation’值”的需求,我们可以使用bfill()。bfill()会从Series的末尾开始,用遇到的第一个非NaN值填充其上方的所有NaN。

# 步骤2: 使用 bfill() 填充 NaNdf['new_bfill'] = df['new_temp'].bfill()print("n--- 步骤2结果 (使用 bfill() 填充) ---")print(df[['Colonne 1', 'Dimension 1', 'new_bfill']])

输出结果:

--- 步骤2结果 (使用 bfill() 填充) ---  Colonne 1   Dimension 1 new_bfill0  MTN_LI2      Indicator     RIPP71  MTN_IRU      Indicator     RIPP72  MTN_ACE      Indicator     RIPP73  MTN_IME      Indicator     RIPP74     RIPP7  Organisation     RIPP75    CA_SOT     Indicator     CNW006    CA_OTI     Indicator     CNW007     CNW00  Organisation     CNW008     BSNTF  Organisation     BSNTF9     RIPNJ  Organisation     RIPNJ

这完美地解决了最初的问题描述:“如果Dimension 1不等于Organisation,则该单元格获取其上方(按逻辑,是其下方最近的Organisation值向上填充)的单元格值。”

3. 使用 Series.ffill() 向前填充(向上查找,向下填充)

作为对比,如果需求是“如果不是’Organisation’,则取其上方最近的’Organisation’值”,那么可以使用ffill()。ffill()会从Series的开头开始,用遇到的第一个非NaN值填充其下方的所有NaN。

# 步骤3: 使用 ffill() 填充 NaN (作为对比,解决不同需求)df['new_ffill'] = df['new_temp'].ffill()print("n--- 步骤3结果 (使用 ffill() 填充) ---")print(df[['Colonne 1', 'Dimension 1', 'new_ffill']])

输出结果:

--- 步骤3结果 (使用 ffill() 填充) ---  Colonne 1   Dimension 1 new_ffill0  MTN_LI2      Indicator       NaN1  MTN_IRU      Indicator       NaN2  MTN_ACE      Indicator       NaN3  MTN_IME      Indicator       NaN4     RIPP7  Organisation     RIPP75    CA_SOT     Indicator     RIPP76    CA_OTI     Indicator     RIPP77     CNW00  Organisation     CNW008     BSNTF  Organisation     BSNTF9     RIPNJ  Organisation     RIPNJ

注意,ffill()在遇到第一个Organisation值(RIPP7)之前,无法填充前几个NaN,因为它们上方没有有效值。这说明了ffill()和bfill()在处理起始/结束NaN时的不同行为。

总结与注意事项

高效性: 结合Series.where()和Series.bfill()/Series.ffill()是Pandas中处理这类条件性填充问题的最佳实践。它们是高度优化的矢量化操作,远比基于Python循环的方案快。灵活性: 这种模式非常灵活,可以应用于各种复杂的条件填充场景。where()可以配合任何布尔条件,而bfill()和ffill()则提供了两种基本的填充方向。初始NaN处理:bfill()会填充其上方的NaN,如果Series的开头就是NaN且其下方没有非NaN值,则这些NaN会保留。ffill()会填充其下方的NaN,如果Series的末尾是NaN且其上方没有非NaN值,则这些NaN会保留。链式操作: 在实际应用中,为了代码简洁,通常会将where()和bfill()/ffill()链式调用,例如:df[‘new’] = df[‘Colonne 1’].where(df[‘Dimension 1’].eq(‘Organisation’)).bfill()。

通过掌握where()和填充方法,您可以高效且优雅地解决Pandas中涉及复杂条件和行间依赖的数据转换问题。

以上就是利用Pandas高效创建依赖上一个有效值的条件列的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1367008.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 07:02:55
下一篇 2025年12月14日 07:03:06

相关推荐

  • Python中利用 sys.settrace 精准获取函数调用前一行的代码行号

    本文探讨了如何在Python中获取函数调用前,即上一条被执行语句的行号。传统的 inspect.currentframe().f_back.f_lineno 方法只能获取调用函数本身的行号,无法满足需求。通过引入 sys.settrace 机制,结合自定义的追踪函数和双端队列 (collection…

    2025年12月14日
    000
  • Pandas中基于条件和行间依赖创建新列

    本文详细介绍了如何在Pandas DataFrame中高效创建依赖于其他行值的条件列。通过结合使用Series.where()进行条件赋值和Series.bfill()或Series.ffill()进行缺失值填充,可以灵活地根据当前行或相邻行的特定条件来确定新列的值,从而避免低效的循环操作,提升数据…

    2025年12月14日
    000
  • Python中利用sys.settrace精确获取函数调用前的代码行号

    本文深入探讨如何利用Python的sys.settrace机制,精确捕获函数调用前一个语句的行号。传统方法通常只能获取函数调用本身的行号,而此方法通过自定义追踪函数和定长队列,实现了对代码执行流的细粒度监控,从而提供调用前的上下文信息。这对于高级调试或需要特定代码执行路径信息的场景尤为有用。 在py…

    2025年12月14日
    000
  • PyMuPDF批量处理:为多文件夹内PDF文件添加指定页面

    本文详细介绍了如何使用Python的PyMuPDF(fitz)库,高效地为散布在不同文件夹下的多个PDF文件批量添加指定页面。通过遍历文件系统、读取PDF内容到内存以及利用PyMuPDF的插入和保存功能,用户可以轻松实现将固定页面(如页眉、页脚或补充信息页)插入到现有PDF文件的指定位置,从而自动化…

    2025年12月14日
    000
  • 使用 ChainMap 实现 Python 字典的深度合并

    本文深入探讨了如何利用 Python 的 collections.ChainMap 实现复杂字典的深度合并。针对 ChainMap 默认的浅层合并行为无法满足嵌套字典合并的需求,文章提出了一种自定义 DeepChainMap 类的方法。通过重写 __getitem__ 方法,该方案能够递归地合并具有…

    2025年12月14日
    000
  • pyads通知机制的高效数据处理:基于类的设计与优化实践

    本文深入探讨了如何利用pyads库高效处理PLC实时数据通知。针对高并发、大数据量场景,我们提出并详细阐述了基于类封装的解决方案,以避免全局变量,实现更清晰的状态管理和数据积累。同时,文章还介绍了优化数据解析性能的关键技巧,包括利用原始字节数据与NumPy进行批量处理,旨在帮助开发者构建健壮、高性能…

    2025年12月14日
    000
  • PyADS通知机制与高效数据处理教程

    本教程详细探讨了如何利用 PyADS 库的通知机制,高效、Pythonic地处理来自PLC的大量实时数据。文章介绍了通过类封装回调函数来管理内部状态和累积数据的方法,有效避免了全局变量的使用。同时,教程深入讲解了优化数据解析性能的策略,包括使用 return_ctypes=True 结合 NumPy…

    2025年12月14日
    000
  • Python Requests库中API请求体数据类型与传输方法详解

    本文深入探讨了在使用Python requests库与RESTful API交互时,如何正确处理请求体数据,以避免常见的“数据类型不匹配”错误,例如“tags should be an array”。文章详细解释了requests.post()方法中params、data和json参数的区别与适用场…

    2025年12月14日
    000
  • Python深度合并嵌套字典:扩展ChainMap的实战指南

    本文深入探讨了在Python中合并嵌套字典的挑战,特别是当键冲突时需要进行深度合并的场景。我们将分析collections.ChainMap在处理此类问题时的局限性,并提供一个定制化的DeepChainMap类,通过重写__getitem__方法,实现对嵌套字典的递归合并,从而优雅地解决复杂的字典合…

    2025年12月14日
    000
  • 使用 collections.ChainMap 实现深度字典合并

    本文探讨了如何利用 Python 的 collections.ChainMap 实现深度字典合并。标准 ChainMap 仅提供浅层合并,即遇到重复键时只取第一个值。针对嵌套字典场景,我们通过自定义 DeepChainMap 类并重写其 __getitem__ 方法,使其能够递归地合并相同键下的字典…

    2025年12月14日
    000
  • 解决Windows环境下Python pip install jq失败的方案

    本文旨在解决在Windows操作系统中,通过pip安装jq库时遇到的构建失败问题,特别是当其作为Langchain JSONLoader的依赖时。文章将提供一种有效的解决方案:利用预编译的.whl文件进行手动安装,并详细指导安装步骤,同时指出使用此方法的相关注意事项,确保用户能在Windows上成功…

    2025年12月14日
    000
  • Python批量API请求处理:数据整合、限流与错误管理

    本文旨在指导如何使用Python高效地处理批量API请求,特别是当输入数据来源于多个列表时。我们将重点探讨如何将这些数据整合、如何通过自定义上下文管理器实现API请求的速率限制,以及如何确保请求的健壮性,通过错误处理机制提升代码的可靠性,最终将结果结构化为Pandas DataFrame。 1. 批…

    2025年12月14日
    000
  • Python中通过API获取地理距离:请求限流与数据整合实践

    本教程详细讲解如何利用Python通过外部API计算地理位置间的驾驶距离,并重点介绍如何实现API请求的限流以遵守服务条款。文章涵盖了API调用函数的构建、基于上下文管理器的智能限流机制、鲁棒的错误处理方法,以及最终将所有数据(包括原始坐标和计算出的距离)整合到Pandas DataFrame中的完…

    2025年12月14日
    000
  • 通过Python实现API请求限速与批量地理距离计算

    本教程详细介绍了如何使用Python高效且负责任地通过API计算两点间的驾驶距离。文章从基础的API调用函数出发,深入探讨了利用contextlib模块实现API请求限速的策略,以避免因请求频率过高而被服务器拒绝。此外,教程还强调了API响应错误处理的重要性,并提供了将计算结果整合到Pandas D…

    2025年12月14日
    000
  • 解决Windows上Python安装jq库失败的问题

    本文针对Windows用户在使用Python的Langchain库中JSONLoader时,因jq库安装失败(常见错误为Failed to build jq)的问题,提供了一套有效的解决方案。核心方法是利用预编译的.whl文件进行离线安装,详细指导了下载和安装步骤,并强调了使用该方案的注意事项和潜在…

    2025年12月14日
    000
  • 使用Python通过API计算地理距离:数据整合与API速率限制实践

    本文旨在指导读者如何使用Python高效地通过外部API计算地理位置间的驾驶距离。内容涵盖了从多源列表数据中提取信息、构建API请求、集成OSRM路由服务进行距离计算的核心方法,并重点介绍了如何利用Python的contextlib.contextmanager实现健壮的API请求速率限制机制,以避…

    2025年12月14日
    000
  • Python批量API调用与限流策略:高效处理多源地理数据

    本文详细介绍了如何使用Python处理来自多个列表的地理坐标数据,并通过API批量计算驾驶距离。核心内容包括利用zip函数高效迭代多组坐标,集成requests库进行API调用,以及通过自定义上下文管理器实现API请求的智能限流,确保程序稳定运行并遵守API服务条款。文章还强调了API响应错误处理的…

    2025年12月14日
    000
  • Python中如何检测不兼容的类型比较操作?

    1.最靠谱的解决python中不兼容类型比较的方法是使用静态类型检查工具如mypy;2.通过类型提示明确变量、函数参数和返回值的类型;3.mypy会在代码运行前分析类型是否匹配,提前发现潜在问题;4.相比运行时错误处理,静态检查能更早发现问题并减少调试成本;5.对于自定义类,需合理实现__eq__、…

    2025年12月14日 好文分享
    000
  • Python屏蔽输出信息如何在异常处理中隐藏堆栈信息 Python屏蔽输出信息的堆栈信息管控方法​

    使用logging模块记录异常,通过配置不同handler分别向用户输出简洁错误信息、向开发者记录完整堆栈;2. 自定义sys.excepthook以控制未捕获异常的输出行为,屏蔽堆栈并显示友好提示;3. 临时重定向sys.stderr以完全抑制标准错误输出,适用于特定代码块;4. 通过调整第三方库…

    2025年12月14日
    000
  • Snakemake动态参数管理:链式依赖与函数封装实践

    本文旨在解决Snakemake规则中参数链式依赖的问题,即一个params参数需要依赖于同规则中其他params参数的值。直接在params块内进行链式引用会导致NameError。核心解决方案是利用Python函数封装复杂的参数推导逻辑,将所有依赖关系整合到一个可调用对象中,并通过wildcard…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信