新闻中心

Pandas管道操作中合并后创建新列:eval与assign的正确姿势

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

pandas管道操作中合并后创建新列:eval与assign的正确姿势

在Pandas数据处理管道中,当合并两个DataFrame后需要基于现有列计算生成新列时,直接使用assign()或transform()可能因类型错误而失败。本文将介绍两种高效且正确的解决方案:利用DataFrame.eval()进行简洁的字符串表达式求值,以及通过assign()结合lambda函数实现灵活的列计算,从而优化数据处理流程并提升代码可读性。

在Pandas的数据分析工作中,我们经常需要将多个DataFrame合并,并在合并后立即根据现有列执行计算以生成新的数据列。将这些操作封装在链式管道(pipeline)中,可以显著提高代码的可读性和维护性。然而,在尝试通过assign()或transform()方法在管道中创建新列时,初学者可能会遇到TypeError,尤其是在直接引用列名进行数学运算时。

理解问题:管道中新列计算的挑战

假设我们有两个DataFrame,solar_part和solar_aod,它们通过pool列进行合并:

import pandas as pd

solar_part = pd.DataFrame(
     {'pool': 1,
     'orig': 635.1}, index = [0]
     )

solar_aod = pd.DataFrame(
     {'pool': [1,1,1,1],
      'MoP': [1,2,3,4],
     'prin': [113.1, 115.3, 456.6, 234.1]}
     )

我们的目标是在合并后,基于prin和orig两列计算一个新的列remn(例如,remn = prin / orig)。一个常见的尝试是直接在assign()中使用列名字符串:

# 错误示范
# solar_p = (
#     solar_aod
#     .merge(solar_part, on = ['pool'], how = 'left')
#     .assign(remn = ['prin'] / ['orig']) # 或 assign(remn = 'prin' / 'orig')
#     )

这种写法会导致TypeError: unsupported operand type(s) for /: 'list' and 'list'(或'str' and 'str'),因为assign()在默认情况下会将'prin'或['prin']解释为字符串字面量或字符串列表,而不是DataFrame中的列引用。因此,不能直接对这些字面量执行数学运算。

为了在管道中高效且正确地完成这类操作,Pandas提供了几种解决方案。

解决方案一:利用 DataFrame.eval() 简化表达式计算

DataFrame.eval()方法允许我们以字符串形式定义表达式,并在DataFrame的上下文中执行它们。这使得它非常适合在管道中创建新列,特别是当表达式涉及多个现有列的简单数学运算时。

使用eval()的优点在于其简洁性和效率,Pandas会在底层优化这些字符串表达式的计算。

solar_p_eval = (
    solar_aod
    .merge(solar_part, on='pool', how='left')
    .eval('remn = prin / orig')
)

print(solar_p_eval)

输出结果:

   pool  MoP   prin   orig      remn
0     1    1  113.1  635.1  0.178082
1     1    2  115.3  635.1  0.181546
2     1    3  456.6  635.1  0.718942
3     1    4  234.1  635.1  0.368603

eval()方法直接将字符串'remn = prin / orig'解析为在当前DataFrame上执行的操作,其中prin和orig被正确识别为列名。

美图云修 美图云修

商业级AI影像处理工具

美图云修 50 查看详情 美图云修

解决方案二:assign() 结合 lambda 函数的灵活性

虽然eval()在处理简单表达式时非常强大,但assign()方法通过结合lambda函数提供了更大的灵活性,尤其是在需要执行更复杂的逻辑或调用自定义函数时。

当assign()接收一个可调用对象(如lambda函数)作为参数时,它会将当前的DataFrame作为输入传递给这个函数。这样,我们就可以在lambda函数内部安全地引用DataFrame的列。

solar_p_assign_lambda = (
    solar_aod
    .merge(solar_part, on='pool', how='left')
    .assign(remn = lambda df: df['prin'] / df['orig'])
)

print(solar_p_assign_lambda)

输出结果:

   pool  MoP   prin   orig      remn
0     1    1  113.1  635.1  0.178082
1     1    2  115.3  635.1  0.181546
2     1    3  456.6  635.1  0.718942
3     1    4  234.1  635.1  0.368603

在这个例子中,lambda df: df['prin'] / df['orig']接收合并后的DataFrame df,然后通过df['prin']和df['orig']正确访问到相应的列Series,并执行逐元素的除法运算。

注意事项与最佳实践

  1. 选择方法:

    • eval(): 适用于涉及简单数学运算符(+, -, *, /, **等)和比较运算符的列间计算。它的语法更简洁,对于大型数据集可能具有性能优势,因为它通常会利用NumPy进行优化。
    • assign() + lambda: 提供更高的灵活性。当你需要执行更复杂的逻辑,例如条件判断、调用自定义函数、或者链式应用多个Pandas方法来生成新列时,lambda函数是更好的选择。
  2. 可读性: 管道操作(pipe、链式调用)本身就旨在提高代码的可读性。选择最能清晰表达意图的方法至关重要。对于简单的列计算,eval()通常更直观。

  3. 性能: 对于大规模数据,eval()在某些情况下可能会比assign与lambda的组合更快,因为它能够利用numexpr库进行优化。然而,对于大多数常见场景,两者的性能差异可能不明显。

  4. 避免直接字符串运算: 记住,在assign()中直接使用字符串字面量进行运算是无效的。必须通过可调用对象(如lambda)来访问DataFrame的列。

总结

在Pandas的数据处理管道中,合并数据后创建新列是一个常见需求。为了避免TypeError并保持代码的简洁性,我们推荐使用DataFrame.eval()进行简单的列间数学运算,或者使用assign()结合lambda函数来处理更复杂的计算逻辑。这两种方法都能优雅地融入Pandas的链式操作,显著提升数据处理代码的效率和可维护性。理解它们的适用场景和工作原理,将帮助你更高效地利用Pandas进行数据分析。

以上就是Pandas管道操作中合并后创建新列:eval与assign的正确姿势的详细内容,更多请关注其它相关文章!


# 因为它  # 海外视频推广网站营销  # 外贸人员seo的血泪  # 德州SEO整站优化招商电话  # 临汾关键词排名提升费用  # 北京西单营销推广  # 怎么做seo推广优化  # 猪八戒推广的营销手段  # 网站推广托管哪家好  # 勒流seo优化教程  # 怎样做好微信营销推广员  # 代码可读性  # 道中  # 并在  # 多个  # 美图  # 是在  # 数据处理  # 自定义  # 运算符  # 链式 


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


相关推荐: 汽车之家官方网站官网入口_汽车之家网页版直接进入  J*aScript实现动态背景色下的文本与按钮颜色自适应调整  智慧团建扫码登录入口 智慧团建扫码登录入口官网版​  AO3访问入口汇总 AO3网页版同人作品一键直达  在J*a中如何开发简易仓库管理与库存统计_仓库管理库存统计项目实战解析  在J*aScript中复现SciPy的B样条拟合与求值:关键考量  Excel文件在线转换快速入口 Excel在线格式转换网站  在J*a中如何开发在线活动报名与管理系统_活动报名管理项目实战解析  解决深度学习模型训练初期异常高损失与完美验证准确率问题  Win11如何开启讲述人功能 Win11屏幕阅读器(讲述人)开启与关闭【教程】  qq浏览器如何查看和导出已保存的密码 qq浏览器密码管理器数据备份教程  内存检查:在VS Code中调试C++时的内存视图  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  深入理解Go语言中的指针类型:以*string为例  PySpark中高效提取字符串右侧可变长度数字:使用regexp_extract  如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略  荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】  c++项目目录结构应该如何组织_c++工程化项目结构规范  C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能  qq音乐在线播放入口_qq音乐电脑版登录链接  Mac怎么查看崩溃日志_Mac控制台错误报告分析  AO3最新镜像入口 Archive of Our Own官方平台访问  Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】  4399免费游戏网址入口 4399小游戏免费入口点开即玩  漫蛙官网正版漫画入口 漫蛙2官方网页登录地址  使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性  千牛数据看板网页版_千牛数据看板网页版访问方法  解决Python单元测试中Mock异常方法调用计数为零的问题  曝R星经典之作开发图 设计简陋但信息密集!  优化大型XML文件解析:基于Python流式处理的内存高效方案  PDF怎么合并PDF并保持格式_PDF合并文件保持排版教程  CSS自定义字体样式被系统字体替换怎么办_font-face方式指定font-display控制渲染策略  Win11怎么隐藏桌面图标 Win11一键隐藏所有桌面元素及恢复显示  邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧  Tabulator表格日期时间排序问题及自定义解决方案  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  将JSON对象数组转置为键值对列表的实用指南  中兴Axon42Ultra怎样在文件App筛图_iPhone中兴Axon42Ultra文件App筛图【图片筛选】  FullCalendar 自定义按钮样式定制指南  TikTok网页版直接登录 TikTok网页端官方平台入口  利用Bokeh CustomJS动态控制DataTable列可见性  PowerPoint如何制作滚动字幕结尾彩蛋_PowerPoint路径动画实现平滑滚动字幕效果  怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法  C++ vector二维数组定义_C++ vector of vector用法  聚水潭ERP登录页面入口 聚水潭ERP官网登录界面  4399体育竞技小游戏_4399小游戏赛事入口  UC浏览器官网入口2025最新 UC浏览器网页版正式地址  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具  QQ邮箱网页版入口登录 QQ邮箱在线邮箱官方通道 

搜索