Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Pandas DataFrame中基于条件更新列值:原理与实践_创想鸟

Pandas DataFrame中基于条件更新列值:原理与实践

Pandas DataFrame中基于条件更新列值:原理与实践

本文旨在解决Pandas DataFrame中根据匹配条件更新子集行值时常见的陷阱。许多用户尝试通过链式索引操作(如set_index().loc[…])进行更新,但此方法通常因操作的是DataFrame的副本而非视图而失败。我们将深入探讨这一失败原因,并提供两种高效且可靠的解决方案:一是利用merge和combine_first适用于范围索引的场景;二是提供一种更为通用的、支持原地更新的merge组合方案,适用于任意索引类型。

理解链式索引赋值的陷阱

在pandas中,当尝试根据另一个dataframe (df2) 的匹配条件来更新第一个dataframe (df1) 的部分行时,一个常见的错误是使用链式索引操作,例如:

import pandas as pddf1 = pd.DataFrame({'a':(1,2,3,4),'b':(10,20,30,40),'c':(100,200,300,400)})df2 = pd.DataFrame({'a':(1,2,3),'b':(10,20,30),'c':(1111,2222,3333)})print("原始 df1:")print(df1)print("ndf2:")print(df2)# 尝试进行更新df1.set_index(['a', 'b']).loc[df2.set_index(['a', 'b']).index, 'c'] = df2.cprint("n尝试更新后的 df1 (未成功):")print(df1)

输出结果:

原始 df1:   a   b    c0  1  10  1001  2  20  2002  3  30  3003  4  40  400df2:   a   b     c0  1  10  11111  2  20  22222  3  30  3333尝试更新后的 df1 (未成功):   a   b    c0  1  10  1001  2  20  2002  3  30  3003  4  40  400

如您所见,df1 的 ‘c’ 列并未按照 df2 的值进行更新。这是因为 df1.set_index([‘a’, ‘b’]) 操作返回的是一个新的 DataFrame 对象(一个副本),而不是原始 df1 的视图。随后的 .loc[…] = df2.c 赋值操作仅仅作用于这个临时的副本,一旦该语句执行完毕,这个副本就会被丢弃,原始 df1 保持不变。

为了实现预期的更新效果,我们需要采用能够正确引用并修改原始 DataFrame 的方法。以下是两种推荐的解决方案。

方法一:使用 merge 和 combine_first (适用于范围索引)

当 df1 具有默认的、连续的范围索引时,merge 结合 combine_first 是一个简洁且高效的解决方案。这种方法通过合并两个 DataFrame 来获取更新值,然后用原始值填充未匹配的空值。

import pandas as pddf1 = pd.DataFrame({'a':(1,2,3,4),'b':(10,20,30,40),'c':(100,200,300,400)})df2 = pd.DataFrame({'a':(1,2,3),'b':(10,20,30),'c':(1111,2222,3333)})# 使用 merge 和 combine_first 更新 df1# 1. 提取 df1 的关键列 'a', 'b',并与 df2 进行左合并#    这将为匹配的行引入 df2 的 'c' 值,未匹配的行 'c' 值将为 NaNmerged_df = df1[['a', 'b']].merge(df2, on=['a', 'b'], how='left')# 2. 使用 combine_first 将 merged_df 中的 NaN 值替换为 df1 中对应的原始 'c' 值#    并将结果赋值给 df1 的 'c' 列df1['c'] = merged_df['c'].combine_first(df1['c'])print("n使用 merge 和 combine_first 更新后的 df1:")print(df1)

代码解释:

df1[[‘a’, ‘b’]].merge(df2, on=[‘a’, ‘b’], how=’left’):我们首先从 df1 中选择用于匹配的列 [‘a’, ‘b’]。然后,将这个子集与 df2 进行左合并 (how=’left’)。这意味着保留 df1 的所有行,并根据 [‘a’, ‘b’] 的匹配情况从 df2 中引入 c 列的值。如果 df1 中的 (a, b) 组合在 df2 中有匹配,则合并结果中的 c 列将是 df2 的 c 值。如果 df1 中的 (a, b) 组合在 df2 中没有匹配,则合并结果中的 c 列将是 NaN。merged_df[‘c’].combine_first(df1[‘c’]):combine_first 方法用于将两个 Series 组合起来。它会优先使用调用者 Series(merged_df[‘c’])的值,如果该位置为 NaN,则会使用传入 Series(df1[‘c’])中对应位置的值。这样,df2 中有匹配的行会使用 df2 的 c 值,而 df2 中没有匹配的行则会保留 df1 原始的 c 值。df1[‘c’] = …: 将最终结果赋值回 df1 的 c 列,实现了原地更新。

预期输出:

使用 merge 和 combine_first 更新后的 df1:   a   b       c0  1  10  1111.01  2  20  2222.02  3  30  3333.03  4  40   400.0

注意: 这里的 c 列数据类型可能会变为浮点型(float64),因为 NaN 值通常以浮点数表示。如果需要保持整数类型,可能需要后续转换,例如 df1[‘c’] = df1[‘c’].astype(int)(但这会要求数据中没有实际的 NaN,或者使用 Pandas 1.0+ 引入的 Int64Dtype)。

方法二:通用且支持原地更新的 merge 组合方案 (适用于任意索引)

当 df1 具有非默认的、自定义的索引,或者需要更精细地控制更新过程时,可以采用以下更通用的 merge 组合方案。此方法通过 reset_index 暂时将索引转换为普通列,进行合并,然后恢复索引并填充 NaN 值。

import pandas as pddf1 = pd.DataFrame({'a':(1,2,3,4),'b':(10,20,30,40),'c':(100,200,300,400)})df2 = pd.DataFrame({'a':(1,2,3),'b':(10,20,30),'c':(1111,2222,3333)})# 为了演示非默认索引,我们先给 df1 设置一个自定义索引# df1 = df1.set_index('a') # 假设 df1 的索引是 'a' 列# print("带有自定义索引的 df1:")# print(df1)# 通用更新方案# 1. 重置 df1 的索引,将原始索引保存为名为 'index' 的列temp_df = df1.reset_index()# 2. 将 temp_df 与 df2 进行左合并,基于 'a' 和 'b'#    合并结果中的 'c' 列将包含来自 df2 的更新值(或 NaN)merged_result = temp_df.merge(df2[['a', 'b', 'c']], on=['a', 'b'], how='left', suffixes=('_df1', '_df2'))# 3. 重新设置索引为原始索引,并选择来自 df2 的 'c' 列(即 'c_df2')#    如果 df2 没有匹配,则 'c_df2' 为 NaNupdated_c_series = merged_result.set_index('index')['c_df2']# 4. 使用 df1 原始的 'c' 值填充 NaNdf1['c'] = updated_c_series.fillna(df1['c'])print("n使用通用 merge 方案更新后的 df1:")print(df1)

代码解释:

df1.reset_index(): 这一步至关重要。它将 df1 的当前索引转换为一个普通的数据列(默认名为 ‘index’),并为 DataFrame 创建一个新的默认范围索引。这样做是为了在合并过程中保留原始行的位置信息。.merge(df2[[‘a’, ‘b’, ‘c’]], on=[‘a’, ‘b’], how=’left’, suffixes=(‘_df1’, ‘_df2’)):将重置索引后的 df1(现在包含原始索引列)与 df2 进行左合并。suffixes=(‘_df1’, ‘_df2’) 用于处理合并后可能出现的同名列。在这里,如果 df1 和 df2 都有 c 列,合并后将分别变为 c_df1 和 c_df2。我们主要关心 df2 中的 c 值,所以会选择 c_df2。.set_index(‘index’)[‘c_df2’]:将合并结果的索引重新设置回原始的索引(即之前保存的 ‘index’ 列)。然后选择 c_df2 列,它包含了来自 df2 的更新值,或者在没有匹配时为 NaN。.fillna(df1[‘c’]): 使用 df1 原始的 c 列值来填充 updated_c_series 中的 NaN 值。这样,只有在 df2 中找到匹配的行才会被更新,其他行保持不变。df1[‘c’] = …: 将最终处理过的 Series 赋值回 df1 的 c 列。

预期输出:

使用通用 merge 方案更新后的 df1:   a   b       c0  1  10  1111.01  2  20  2222.02  3  30  3333.03  4  40   400.0

注意事项

键的唯一性: 上述两种方法都假设 df2 中用于匹配的组合键(例如 [‘a’, ‘b’])是唯一的。如果 df2 中存在重复的键组合,merge 操作可能会导致 df1 的行被重复,或者导致不确定的更新结果。在实际应用中,建议在合并前对 df2 的匹配键进行去重或聚合处理。性能: 对于大型 DataFrame,merge 操作通常比基于循环或 apply 的方法更高效,因为它利用了 Pandas 底层的优化。数据类型: 合并和填充操作可能会导致列的数据类型发生变化(例如从 int 变为 float 以容纳 NaN)。如果需要保持特定的数据类型,可能需要在操作完成后进行显式类型转换。选择方法:如果 df1 具有默认的范围索引,并且您更倾向于简洁的代码,方法一 (merge + combine_first) 是一个很好的选择。如果 df1 具有自定义索引,或者您需要更细粒度的控制,方法二(通用 merge 方案)更为健壮。

总结

在 Pandas 中,直接对链式索引操作进行赋值通常不会修改原始 DataFrame,因为它操作的是一个临时副本。为了可靠地根据匹配条件更新 DataFrame 的子集行,我们应采用 merge 等方法来构建包含更新值的新 Series,然后将其赋值回原始 DataFrame 的目标列。无论是通过 merge 和 combine_first 的组合,还是通过 reset_index、merge 和 fillna 的通用方案,都能有效且高效地实现这一目标,同时避免常见的陷阱。理解这些方法背后的原理对于编写健壮的 Pandas 数据处理代码至关重要。

以上就是Pandas DataFrame中基于条件更新列值:原理与实践的详细内容,更多请关注创想鸟其它相关文章!

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

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
SQLAlchemy模型中生成唯一6位ID的策略与实践
上一篇 2025年12月14日 14:15:28
Python字典查找:实现用户输入大小写不敏感的策略
下一篇 2025年12月14日 14:15:32

相关推荐

  • 手机淘宝怎么加热区?淘宝怎么添加热区

    需商家账号在淘宝商家中心或旺铺PC端设置热区,普通买家无权限。①手机端:登录商家中心→店铺管理→详情页装修→选图添加热点→设链接保存;②PC端:登录旺铺官网→店铺装修→用图片热区工具划区域→设跳转链接→发布;③确认账号为已开店的商家主/子账号,未开通需申请店铺并订购旺铺服务。 如果您在使用手机淘宝时…

    2026年9月21日
    000
  • 百度搜索app如何启用搜索关键词过滤_百度搜索app关键词过滤的设置技巧

    可通过减号语法排除关键词,如“健身教程 -广告”;用双引号实现精确匹配,如”瑜伽初学者教程”;结合site:指令限定范围,如Python入门教程 site:zhihu.com,提升搜索精准度。 如果您在使用百度搜索App时,希望减少不相关或不想要的搜索结果,可以通过设置关键词…

    2026年9月21日
    800
  • safari浏览器如何设置链接在新窗口而不是新标签页打开_safari浏览器链接新窗口打开设置

    通过快捷键或第三方扩展可实现Safari中链接在新窗口打开:1. 按住Command键点击链接可临时在新窗口打开;2. 使用AppleScript脚本通过“自动操作”创建快速操作以新建Safari窗口;3. 网站自身代码如window.open()会强制新窗口打开;4. 安装可信扩展如“Link i…

    2026年9月21日
    000
  • Hibernate Search嵌入式对象索引策略与常见问题解决

    本文探讨了在使用Hibernate Search对关联或嵌入式对象进行索引时遇到的常见问题,特别是@IndexedEmbedded与includePaths属性的结合使用。通过分析HSEARCH000216错误,揭示了嵌入式对象属性需要显式@Field注解才能被主实体索引的机制,并提供了具体的代码示…

    2026年9月21日
    100
  • 腾讯动漫VIP会员怎么免费领取_腾讯动漫VIP限时免费领取教程

    可通过官方活动免费领取腾讯动漫VIP。①在腾讯视频APP任务中心用积分兑换,300积分换1天;②关注“腾讯动漫VIP”公众号,发送关键词参与活动获体验卡;③节假日留意APP内“全站限免”活动,直接观看VIP内容或领取免费时长。 如果您希望在不付费的情况下获得腾讯动漫VIP会员的观看权限,可能是因为官…

    2026年9月21日
    000
  • 为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源

    为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源为什么iPhone14Plus系统更新后屏幕失灵如何强制重启?快速按音量键后按电源

    如果您尝试访问某个网站,但服务器无法访问,则可能是由于服务器 IP 地址无法解析。以下是解决此问题的步骤: 本文运行环境:iPhone 14 Plus,iOS 18。 一、强制重启设备 当iPhone 14 Plus在系统更新后出现屏幕失灵、无响应或触控失效时,强制重启是一种有效的硬件级恢复手段,可…

    2026年9月21日 • 用户投稿
    200
  • PHP中基于参考数组过滤多维数组并保持结构一致性

    本教程详细阐述了如何在PHP中,根据一个参考数组来过滤多维数组的特定子数组,并同步移除其他子数组中对应索引的元素,最终实现数组的结构化筛选和重新索引。文章通过实际案例和代码演示,指导读者高效地处理复杂数组的匹配与清理任务。 在php开发中,我们经常会遇到需要对复杂数据结构进行筛选和整理的场景。例如,…

    2026年9月21日
    100
  • 美图秀秀图片亮度无法调节怎么办 美图秀秀亮度调整与修复方法

    亮度调不了可能是未进入“美化”或“编辑”模式,需确认已正确导入图片并找到亮度滑块;2. 软件版本过旧或缓存异常会导致功能失效,应更新美图秀秀或重启程序,电脑版可尝试以管理员身份运行;3. 不同设备可能存在兼容性问题,建议切换手机App或电脑客户端测试,手机用户可清除缓存或重装应用;4. 若功能仍不可…

    2026年9月21日
    100
  • 长佩阅读如何自定义封面

    在长佩阅读中,设置自定义封面可以让你的书架更具个人风格。以下是具体操作步骤: 一、确认书籍是否支持自定义封面 并非所有书籍都开放自定义封面功能,你需要先进入书籍详情页查看是否存在“自定义封面”这一选项。若该按钮存在,则说明这本书允许用户更换封面。 二、准备合适的封面图片 选择一张你喜欢的图片作为新封…

    2026年9月21日
    000
  • Laravel 8 登录后重定向到仪表盘的完整教程

    本教程详细介绍了在 Laravel 8 中实现用户登录后重定向到仪表盘的多种方法。我们将探讨如何利用 Laravel 内置的 $redirectTo 属性,以及如何通过重写 LoginController 中的 login 方法来实现自定义重定向逻辑。此外,教程还将重点讲解正确的路由配置和中间件使用…

    2026年9月21日
    100
  • 探探App如何更新应用版本_探探App应用版本更新教程及自动升级设置

    打开App Store点击更新标签,找到探探并手动点击更新;2. 开启自动更新需进入设置-App Store,打开自动下载的App更新开关;3. 搜索探探查看是否显示“更新”以确认版本状态。 探探App更新很简单,无论是手动升级还是设置自动更新,都能快速用上最新版本。下面告诉你具体怎么操作。 手动更…

    2026年9月21日
    000
  • 番茄免费小说怎么用QQ登录_番茄免费小说QQ登录教程

    首先通过登录界面点击“QQ登录”授权进入,或在账号设置中绑定QQ;若已绑定手机号,则需输入验证码完成验证,最后确认授权即可成功登录。 如果您希望在番茄免费小说中使用QQ账号进行登录,但找不到正确的操作入口或遇到授权问题,可以按照以下方法尝试。这些步骤能帮助您完成账号关联和登录流程。 本文运行环境:小…

    2026年9月21日
    200
  • iPhone14首次使用时应禁用的几项功能

    哪些功能在新机设置时建议关闭? 1. “定位服务” 启用定位服务后,各类应用可获取您的实时位置,虽然有助于导航或本地推荐,但也可能造成位置信息被滥用。若重视个人隐私,建议进入设置关闭该权限,限制应用对地理位置的访问。 2. “后台应用刷新” 此功能使应用程序在未打开时也能在后台获取最新内容,提升使用…

    2026年9月21日
    000
  • 如何从被调用类中获取调用者文件的命名空间

    本文探讨了在PHP中,如何在不通过参数传递的情况下,从一个被调用的工具类中获取到调用该方法的文件的命名空间。通过结合使用`debug_backtrace()`回溯调用栈以定位调用者文件,并利用`token_get_all()`解析文件内容来提取命名空间声明,提供了一种实用的解决方案。文章详细介绍了实…

    2026年9月21日
    100
  • 美团外卖节日优惠券领取入口_美团节日活动优惠券获取方法

    节日期间可通过美团外卖首页“膨胀红包”、搜索品牌关键词、参与“神抢手”秒杀、邀请好友助力及关注官方社交媒体口令等五种方法领取优惠券,具体包括完成任务积累红包、领取0元饮品券、抢购低价商品券、获取大额免单券和兑换口令红包。 如果您在节日期间准备通过美团外卖订餐,但未能找到可用的优惠券入口,则可能是由于…

    2026年9月21日
    100
  • MAC系统磁盘空间不足怎么办_Mac磁盘空间清理与管理技巧

    Mac存储空间不足时,应先使用系统自带的存储管理工具分析并优化存储,通过“关于本机”进入“管理”界面,启用优化选项;接着手动删除不常用应用及其在Application Support和Caches中的残留文件;再进入资源库清理Caches和Logs中的缓存与日志;随后在“避免杂乱”中查找并删除大型无…

    2026年9月21日
    000
  • Android应用中实现游戏循环与UI更新的正确姿势

    本文旨在解决Android应用开发中,开发者尝试使用传统游戏循环(如while(running))导致应用无响应或崩溃的问题。核心内容是阐明Android事件驱动的UI模型,指导开发者如何正确初始化UI组件、设置事件监听器,并通过事件回调机制实现逻辑更新和UI刷新,避免阻塞主线程,确保应用的流畅运行…

    2026年9月21日
    700
  • bilibili客户端如何开启省流量模式_bilibili客户端省流量功能的设置指南

    首先调整默认视频清晰度至“流畅”或“480P”,再开启省流播放模式以优化数据传输,最后关闭自动缓存与预加载功能,从而有效降低B站移动数据消耗。 如果您在使用移动数据网络观看B站视频时发现流量消耗过快,可能是未开启针对性的省流量设置。通过调整客户端内的相关选项,可以有效降低数据使用量。以下是具体的操作…

    2026年9月21日
    000
  • MAC的随航(Sidecar)功能怎么使用_MAC Sidecar功能使用教程

    首先确认设备兼容性,确保Mac和iPad满足硬件与系统要求,并登录同一Apple ID。接着开启Wi-Fi和蓝牙,使两设备处于同一网络。通过控制中心“显示器”选项选择iPad名称,无线连接即可建立;或使用数据线进行有线连接以获得更稳定体验。连接后可在“系统设置-显示器-随航”中配置扩展或镜像模式,启…

    2026年9月21日
    000
  • Java中高效查找时空事件重叠的方法

    本文探讨了在Java中高效查找具有空间和时间范围定义的事件之间重叠的解决方案。核心思想是将时空事件编码为二维矩形,然后利用专业的空间索引结构(如R树、四叉树或PH树)进行快速查询。通过这种方法,可以显著提升在大规模数据集中识别事件重叠的效率,并提供了使用Tinspin索引库的示例代码和实践建议。 时…

    2026年9月21日
    100

发表回复

登录后才能评论
关注微信