Pandas与NumPy:高效实现多列条件赋值与来源追踪

Pandas与NumPy:高效实现多列条件赋值与来源追踪

本文探讨了在Pandas DataFrame中根据条件从多列选择值并追踪其来源的有效方法。针对numpy.select无法直接返回多列的局限性,文章介绍了一种利用DataFrame.notna().argmax(1)结合NumPy高级索引的优化方案,该方案能够简洁高效地实现从多个候选列中提取首个非空值及其对应的列名,显著提升代码的可读性和执行效率。

1. 问题背景:多列条件赋值的挑战

在数据处理中,我们经常需要根据特定条件从dataframe的多个列中选择一个值,并同时记录该值的来源列。例如,给定一个dataframe,其中包含多列可能的数据源,我们希望创建一个新列来存储首个有效(非空)值,并创建另一个新列来记录该值的原始列名。

考虑以下DataFrame示例:

import pandas as pdimport numpy as npdata = {'A': [1.0, 2.0, np.nan], 'B': [4, 5, 6]}df = pd.DataFrame(data)print("原始DataFrame:")print(df)

期望的输出是这样的:

   A  B  val val_source0  1.0  4  1.0          A1  2.0  5  2.0          A2  NaN  6  6.0          B

初次尝试时,开发者可能会倾向于使用numpy.select,因为它允许根据条件数组选择不同的“选择”数组。然而,np.select的一个限制是,它期望每个“选择”项都是一个单一的数组或Series,而不能直接返回一个包含多列的DataFrame。

例如,以下尝试会引发错误:

# 这种尝试会报错,因为np.select不支持返回多列# conds = [df['A'].notna(), True]# choices = [df[['A']].assign(val_source='A'), df[['B']].assign(val_source='B')]# df[['val', 'val_source']] = np.select(conds, choices)

为了规避这一限制,常见的做法是执行两次独立的np.select操作,即使它们的条件逻辑完全相同:

# 常见的双次np.select workaroundconds = [df['A'].notna(), True]_choices_val_src = [    (df['A'], 'A'),    (df['B'], 'B'),]choices_val, choices_src = zip(*_choices_val_src)df_copy = df.copy() # 使用副本避免修改原始dfdf_copy['val'] = np.select(conds, choices_val, default=np.nan)df_copy['val_source'] = np.select(conds, choices_src, default=np.nan)print("n使用两次np.select的结果:")print(df_copy)

虽然这种方法能够实现目标,但当需要处理的候选列数量很多时,代码会显得冗长且存在重复计算,不够优雅和高效。

2. 高效解决方案:利用argmax与高级索引

对于“选择第一个非空值及其来源”这类特定场景,Pandas和NumPy提供了一种更为简洁和高效的解决方案,它利用了DataFrame.notna().to_numpy().argmax(axis=1)来找到每行中第一个非空值的列索引,然后结合NumPy的高级索引特性来提取值和列名。

# 原始DataFramedata = {'A': [1.0, 2.0, np.nan], 'B': [4, 5, 6]}df = pd.DataFrame(data)# 1. 识别每行第一个非空值的列索引# df.notna() 返回一个布尔型DataFrame,指示每个元素是否为非空# .to_numpy() 将布尔型DataFrame转换为NumPy数组# .argmax(1) 沿着行方向(axis=1)找到第一个True(即第一个非空值)的索引# 如果一行全是False(即全是NaN),argmax会返回0(第一个列的索引),这需要注意后续处理idx = df.notna().to_numpy().argmax(1)print("n每行第一个非空值的列索引 (idx):")print(idx)# 2. 提取对应的值# df.to_numpy() 将整个DataFrame转换为NumPy数组# (df.index, idx) 创建一个元组,用于NumPy的高级索引# df.index 提供了行的索引(0, 1, 2...)# idx 提供了列的索引(0代表A,1代表B...)# 这样,对于每一行,我们都精确地取到了其在idx中指定的列的值df['val'] = df.to_numpy()[(df.index, idx)]# 3. 提取对应的列名作为来源# df.columns 是DataFrame的列名列表# df.columns[idx] 使用之前计算的列索引idx来直接获取对应的列名df['val_source'] = df.columns[idx]print("n使用argmax和高级索引的结果:")print(df)

代码解析:

idx = df.notna().to_numpy().argmax(1):

df.notna(): 生成一个与df形状相同的布尔型DataFrame,其中True表示非空,False表示空(NaN)。.to_numpy(): 将布尔型DataFrame转换为NumPy数组,这是为了利用NumPy的argmax函数。.argmax(1): 在NumPy数组上沿着行方向(axis=1)查找第一个True值(即第一个非空值)的索引。如果一行中所有值都为False(即所有列都为NaN),argmax会返回0,表示第一个列的索引。在我们的例子中,由于至少有一个非空值(或者我们希望默认取第一个),这通常是可接受的行为。

df[‘val’] = df.to_numpy()[(df.index, idx)]:

df.to_numpy(): 将整个DataFrame转换为NumPy数组,以便进行高效的NumPy索引操作。[(df.index, idx)]: 这是NumPy的高级索引技巧。它接收一个元组,其中第一个元素是行的索引数组,第二个元素是列的索引数组。df.index提供了默认的行索引(0, 1, 2…),而idx提供了我们计算出的每行对应的列索引。通过这种方式,NumPy能够一次性地从df的NumPy表示中精确地提取出每个行在idx指定列上的值。

df[‘val_source’] = df.columns[idx]:

df.columns: 获取DataFrame的所有列名(一个Index对象)。df.columns[idx]: 直接使用idx数组作为索引来从df.columns中选择对应的列名。由于idx包含了每个行对应的列索引,这里将直接映射出这些列的名称。

3. 优势与适用场景

简洁性: 相较于多次调用np.select,此方法代码量更少,逻辑更集中。效率: 利用了NumPy的矢量化操作,对于大型DataFrame,其执行效率通常高于基于循环或多次条件判断的方法。可读性: 对于“选择第一个有效值”这类特定需求,argmax的语义清晰,代码意图明确。

适用场景:

此方法特别适用于以下场景:

从一系列优先级递减的列中选择第一个非空值。每行至少有一个非空值,或者可以接受当所有列都为NaN时默认选择第一个列的值(这可能仍然是NaN)。

注意事项:

如果一行中所有列都是NaN,argmax(1)将返回0(即第一列的索引),这意味着val会是第一列的NaN值,而val_source会是第一列的名称。请根据实际业务需求判断这是否是期望的行为。如果需要对这种情况进行特殊处理(例如,赋一个默认值或标记为“无来源”),则可能需要额外的逻辑。此方法侧重于“第一个匹配”的场景。如果条件逻辑更复杂,例如需要基于多个列的组合条件,或者需要选择的不是第一个非空值而是满足特定复杂条件的某个值,那么拆分np.select或使用apply函数可能更具灵活性。

4. 总结

在Pandas中进行多列条件赋值并追踪来源是一个常见的需求。尽管numpy.select在直接返回多列方面存在局限性,但通过巧妙地结合DataFrame.notna().to_numpy().argmax(1)和NumPy的高级索引,我们可以为“选择第一个非空值及其来源”这一特定问题提供一个极其高效和简洁的解决方案。掌握这种技巧将有助于编写更优雅、更具性能的Pandas数据处理代码。

以上就是Pandas与NumPy:高效实现多列条件赋值与来源追踪的详细内容,更多请关注创想鸟其它相关文章!

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

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Selenium WebDriver驱动管理与资源释放:现代实践指南
上一篇 2025年12月14日 03:53:32
如何使用Python计算移动分位数—rolling+quantile组合技巧
下一篇 2025年12月14日 03:53:40

相关推荐

  • 如何在Java方法中正确传递和使用数组参数

    如何在Java方法中正确传递和使用数组参数如何在Java方法中正确传递和使用数组参数如何在Java方法中正确传递和使用数组参数如何在Java方法中正确传递和使用数组参数

    本文旨在帮助Java初学者理解如何在方法中正确传递和使用数组作为参数。通过一个实际的代码示例,详细讲解了如何创建、传递和访问数组,以及如何在方法内部对数组进行操作,最终返回期望的结果。掌握这些技巧对于编写高效且功能完善的Java程序至关重要。 在Java编程中,方法经常需要接收数组作为参数,以便对一…

    2026年9月26日 • 用户投稿
    300
  • 抖音任务接单平台微信小程序是什么

    抖音任务接单平台微信小程序是什么抖音任务接单平台微信小程序是什么抖音任务接单平台微信小程序是什么抖音任务接单平台微信小程序是什么

    抖音任务接单平台微信小程序是一款专为抖音内容创作者打造的高效变现工具。 该小程序集成了任务获取、进度管理、收入统计、智能提醒等多项实用功能,帮助用户更便捷地完成商业合作,提升在抖音平台的内容变现能力。 抖音任务接单平台微信小程序的核心功能 任务接单:高效匹配 通过抖音任务接单平台微信小程序,用户可以…

    2026年9月26日 • 用户投稿
    000
  • 货拉拉司机版如何使用AI推荐最佳订单_货拉拉司机版AI推荐的智能匹配详解

    货拉拉司机版如何使用AI推荐最佳订单_货拉拉司机版AI推荐的智能匹配详解货拉拉司机版如何使用AI推荐最佳订单_货拉拉司机版AI推荐的智能匹配详解货拉拉司机版如何使用AI推荐最佳订单_货拉拉司机版AI推荐的智能匹配详解货拉拉司机版如何使用AI推荐最佳订单_货拉拉司机版AI推荐的智能匹配详解

    货拉拉司机版通过AI智能匹配系统,基于位置、车辆类型、货运需求与历史行为等数据筛选高匹配订单,并结合AR识货、智能导航与安全预警功能,提升接单效率与运输安全。 如果您在货拉拉司机版中希望获得更高效的接单体验,但不清楚如何利用系统内的AI功能来获取最适合的订单,则可能是由于尚未了解智能匹配机制的运作方…

    2026年9月26日 • 用户投稿
    200
  • 通过Intent将图片分享至Adobe Lightroom (Android)

    通过Intent将图片分享至Adobe Lightroom (Android)通过Intent将图片分享至Adobe Lightroom (Android)通过Intent将图片分享至Adobe Lightroom (Android)通过Intent将图片分享至Adobe Lightroom (Android)

    本文将介绍如何使用Kotlin代码,通过隐式Intent将Android应用中的图片直接分享至Adobe Lightroom移动版。通过设置Intent的Action、Extra和Type,并指定目标应用的包名,可以实现从自定义应用无缝跳转至Lightroom进行图片编辑的目的。本文将提供详细的代码…

    2026年9月26日 • 用户投稿
    100
  • sublime怎么写latex并编译成pdf_Sublime配置LaTeX编译环境指南

    sublime怎么写latex并编译成pdf_Sublime配置LaTeX编译环境指南sublime怎么写latex并编译成pdf_Sublime配置LaTeX编译环境指南sublime怎么写latex并编译成pdf_Sublime配置LaTeX编译环境指南sublime怎么写latex并编译成pdf_Sublime配置LaTeX编译环境指南

    首先安装LaTeX发行版,如Windows选TeX Live,macOS用MacTeX,Linux通过包管理器安装;然后在Sublime Text中通过Package Control安装LaTeXTools插件;接着配置LaTeXTools的用户设置,指定tex_path路径、构建方式和PDF查看器…

    2026年9月26日 • 用户投稿
    000
  • Oracle存储过程批量更新实现方法

    Oracle存储过程批量更新实现方法Oracle存储过程批量更新实现方法Oracle存储过程批量更新实现方法Oracle存储过程批量更新实现方法

    标题:Oracle存储过程批量更新实现方法 在Oracle数据库中,使用存储过程批量更新数据是一种常见的操作。通过批量更新可以提高数据处理的效率,减少对数据库的频繁访问,同时也能减少代码的复杂性。本文将介绍如何在Oracle数据库中使用存储过程实现批量更新数据的方法,并给出具体的代码示例。 首先,我…

    2026年9月26日 • 用户投稿
    000
  • 快手视频如何下载保存_快手视频下载保存的简单方法

    快手视频如何下载保存_快手视频下载保存的简单方法快手视频如何下载保存_快手视频下载保存的简单方法快手视频如何下载保存_快手视频下载保存的简单方法快手视频如何下载保存_快手视频下载保存的简单方法

    优先使用快手App内“保存到相册”功能下载公开视频,操作简单且保留原画质;2. 若视频受限制或需无水印版本,可复制链接后通过第三方解析网站提取下载;3. 通用方法为启用手机录屏功能,录制并保存视频内容至相册。 如果您在浏览快手时看到喜欢的视频,想要将其保存到本地设备以便离线观看或分享,但发现部分视频…

    2026年9月26日 • 用户投稿
    000
  • Marshall Kilburn III 体验:50 小时超长续航,在「便携音箱」属性下的一次踏实升级

    Marshall Kilburn III 体验:50 小时超长续航,在「便携音箱」属性下的一次踏实升级Marshall Kilburn III 体验:50 小时超长续航,在「便携音箱」属性下的一次踏实升级Marshall Kilburn III 体验:50 小时超长续航,在「便携音箱」属性下的一次踏实升级Marshall Kilburn III 体验:50 小时超长续航,在「便携音箱」属性下的一次踏实升级

    这两年来,Marshall 似乎都将更新的重点放在耳机上。 ▲ Marshall Major V ▲ Marshall Monitor II 像是提升了舒适度和续航的贴耳头戴 Major V,还有续航变强的同时也增加了 SOUNDSTAGE 环绕音效的 Monitor III,还有在保持原有紧凑设计…

    2026年9月26日 • 用户投稿
    000
  • 《失落之魂》Demo上架PS商店!当前评分为4.27分

    《失落之魂》Demo上架PS商店!当前评分为4.27分《失落之魂》Demo上架PS商店!当前评分为4.27分《失落之魂》Demo上架PS商店!当前评分为4.27分《失落之魂》Demo上架PS商店!当前评分为4.27分

    现在入手《失落之魂》超值优惠来袭,金币抵扣叠加领取“5元”额外折扣券,标准版仅需193.32元起(共节省74.68元),豪华版也低至237.72元(总计优惠90.28元)! 备受瞩目的国产动作大作《失落之魂》已正式上线发售!同时,游戏试玩版Demo已在PlayStation商店和Steam平台同步开…

    2026年9月26日 • 用户投稿
    000
  • 视频号视频怎么加文字?加文字怎么跟着视频走?

    视频号视频怎么加文字?加文字怎么跟着视频走?视频号视频怎么加文字?加文字怎么跟着视频走?视频号视频怎么加文字?加文字怎么跟着视频走?视频号视频怎么加文字?加文字怎么跟着视频走?

    视频号已成为内容创作的重要阵地,而文字是提升视频表现力的关键元素。无论是标题、字幕还是特效文字,恰当的文字运用能让你的视频内容更丰富,传播效果更佳,吸引更多观众停留互动。 一、视频号视频怎么加文字? 1.发布时添加标题和描述 在视频号发布页面,最基础的文字就是标题和描述。标题要简洁有力,用15字以内…

    2026年9月26日 • 用户投稿
    200
  • vivo X300系列重构移动影像体验,全链路创新开启场景化创作新时代

    vivo X300系列重构移动影像体验,全链路创新开启场景化创作新时代vivo X300系列重构移动影像体验,全链路创新开启场景化创作新时代vivo X300系列重构移动影像体验,全链路创新开启场景化创作新时代vivo X300系列重构移动影像体验,全链路创新开启场景化创作新时代

    9月26日,vivo在“x系列蓝图影像技术沟通会”上正式发布全新影像战略,提出以“场景解决方案”为核心,构建开放协同的影像生态,推动移动影像从功能性工具向文化表达载体跃迁。作为这一战略的首款实践之作,vivo x300系列通过全链路技术创新,在画质表现、极限拍摄、旅行人像及视频创作四大维度实现全面突…

    2026年9月26日 • 用户投稿
    000
  • 360极速浏览器账号如何登录和退出_360极速浏览器用户账号登录与注销操作

    360极速浏览器账号如何登录和退出_360极速浏览器用户账号登录与注销操作360极速浏览器账号如何登录和退出_360极速浏览器用户账号登录与注销操作360极速浏览器账号如何登录和退出_360极速浏览器用户账号登录与注销操作360极速浏览器账号如何登录和退出_360极速浏览器用户账号登录与注销操作

    登录360极速浏览器需通过左上角头像或右上角菜单进入登录界面,输入账号密码或使用手机号快捷验证完成登录;如需切换账户或保护隐私,可点击头像后选择退出登录,或通过设置菜单清除Cookie等方式彻底注销并重启浏览器。 如果您在使用360极速浏览器时需要同步收藏夹、设置或使用云服务,则必须先登录您的360…

    2026年9月26日 • 用户投稿
    100
  • 苹果手机wifiwapi收钱吗

    苹果手机wifiwapi收钱吗苹果手机wifiwapi收钱吗苹果手机wifiwapi收钱吗苹果手机wifiwapi收钱吗

    苹果手机连接 WAPI 无线网络无需付费。步骤如下:1. 打开“设置”;2. 进入“无线局域网”;3. 选择 WAPI 无线网络;4. 输入 WAPI 密钥;5. 点击“连接”。 苹果手机连接 WAPI 无线网络是否需要付费? 答案:否 苹果手机连接 WAPI 无线网络不需要付费。WAPI 是一种无…

    2026年9月26日 • 用户投稿
    000
  • Debian系统上Tomcat日志如何备份

    Debian系统上Tomcat日志如何备份Debian系统上Tomcat日志如何备份Debian系统上Tomcat日志如何备份Debian系统上Tomcat日志如何备份

    本文介绍几种在Debian系统上备份Tomcat日志文件的有效方法,帮助您安全地保存和管理重要的日志信息。 方法一:手动备份 找到日志文件: Tomcat日志文件通常位于 /var/log/tomcat 或 /opt/tomcat/logs 目录下。请根据您的实际安装路径进行调整。压缩日志: 使用 …

    2026年9月26日 • 用户投稿
    000
  • ChatGPT能不能读取上传的文件 支持的文件类型及读取方式详解

    ChatGPT能不能读取上传的文件 支持的文件类型及读取方式详解ChatGPT能不能读取上传的文件 支持的文件类型及读取方式详解ChatGPT能不能读取上传的文件 支持的文件类型及读取方式详解ChatGPT能不能读取上传的文件 支持的文件类型及读取方式详解

    本文将围绕ChatGPT读取文件的能力展开详细说明。我们将首先明确此功能的适用范围,接着列举其支持的主要文件类型,最后通过分步教学,引导您完成从上传文件到与其进行智能交互的全过程,帮助您掌握并有效利用这一强大功能。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSee…

    2026年9月26日 • 用户投稿
    100
  • 1688阿里巴巴官网首页 1688阿里巴巴官方平台链接

    1688阿里巴巴官网首页 1688阿里巴巴官方平台链接1688阿里巴巴官网首页 1688阿里巴巴官方平台链接1688阿里巴巴官网首页 1688阿里巴巴官方平台链接1688阿里巴巴官网首页 1688阿里巴巴官方平台链接

    1688阿里巴巴官网首页入口地址是https://www.1688.com,该平台提供多品类一站式采购服务,涵盖交易灵活、供应商广泛等优势。 1688阿里巴巴官网首页入口地址在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来1688阿里巴巴官方平台链接,感兴趣的网友一起随小编来瞧瞧吧! ht…

    2026年9月26日 • 用户投稿
    100
  • Linux如何从源码编译安装软件_configure与make命令详解

    Linux如何从源码编译安装软件_configure与make命令详解Linux如何从源码编译安装软件_configure与make命令详解Linux如何从源码编译安装软件_configure与make命令详解Linux如何从源码编译安装软件_configure与make命令详解

    答案是掌握 ./configure 和 make 的作用与用法可完成 Linux 源码编译安装。1. configure 检查系统环境并生成 Makefile,确保编译条件满足,支持 –prefix、–enable、–with 等选项定制安装;2. make 读取…

    2026年9月26日 • 用户投稿
    000
  • sublime怎么查看历史剪贴板内容_sublime历史剪贴板查看方法

    sublime怎么查看历史剪贴板内容_sublime历史剪贴板查看方法sublime怎么查看历史剪贴板内容_sublime历史剪贴板查看方法sublime怎么查看历史剪贴板内容_sublime历史剪贴板查看方法sublime怎么查看历史剪贴板内容_sublime历史剪贴板查看方法

    安装Clipboard History插件可为Sublime Text添加剪贴板历史功能:通过命令面板搜索并安装该插件后,使用Ctrl+Shift+V(Windows/Linux)或Cmd+Shift+V(Mac)即可调出文本剪贴板历史记录,选择所需内容粘贴,提升编辑效率。 Sublime Text…

    2026年9月26日 • 用户投稿
    100
  • ChatGPT是否能用于语言学习 辅助学习语言的实际案例与建议

    ChatGPT是否能用于语言学习 辅助学习语言的实际案例与建议ChatGPT是否能用于语言学习 辅助学习语言的实际案例与建议ChatGPT是否能用于语言学习 辅助学习语言的实际案例与建议ChatGPT是否能用于语言学习 辅助学习语言的实际案例与建议

    本文将详细探讨如何利用ChatGPT作为语言学习的辅助工具。通过具体的实际案例和清晰的步骤指引,我们将演示如何将其融入日常学习,有效进行对话模拟、语法校对、词汇积累和写作优化,从而帮助学习者掌握一种高效的语言辅助学习方法。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 Dee…

    2026年9月26日 • 用户投稿
    000
  • 联想拯救者主机如何检测固态寿命?SMART 数据解读​

    联想拯救者主机如何检测固态寿命?SMART 数据解读​联想拯救者主机如何检测固态寿命?SMART 数据解读​联想拯救者主机如何检测固态寿命?SMART 数据解读​联想拯救者主机如何检测固态寿命?SMART 数据解读​

    固态硬盘寿命检测主要通过读取smart数据实现,具体方法包括:1.使用联想电脑管家查看硬盘健康状态;2.使用crystaldiskinfo等工具获取详细smart信息;3.选择其他第三方检测软件;4.通过命令行或powershell脚本获取更详细的smart数据。解读crystaldiskinfo时…

    2026年9月26日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信