0

0

Pandas DataFrame中列与列表元素的高效比较与布尔列生成

DDD

DDD

发布时间:2025-10-10 10:09:41

|

831人浏览过

|

来源于php中文网

原创

Pandas DataFrame中列与列表元素的高效比较与布尔列生成

本教程探讨如何在Pandas DataFrame中高效地比较列值与另一列值或第三列中的列表元素,并据此生成一个新的布尔类型列。文章将介绍两种主要方法:利用Python列表推导式实现高性能操作,以及优化Pandas apply 函数以处理复杂逻辑,同时强调处理缺失值(pd.NA)和列表类型数据的最佳实践。

在数据分析和处理中,我们经常需要根据多列的复杂条件来创建新的特征列。一个常见的场景是,我们需要检查某一列(col_x)的值是否等于另一列(col_y)的值,或者是否包含在第三列(col_grp)的列表中。col_grp列可能包含列表,也可能包含缺失值(如pd.na)。

考虑以下示例DataFrame:

import pandas as pd
import numpy as np # np is not strictly needed for pd.NA, but often imported

data = {"col_x": ["1234", "5678", "9876", "1111", "1234", "1234"],
        "col_y": ["1234", "2222", "3333", "1111", "2222", "2222"],
        "col_grp": [pd.NA, ["5678", "9999"], ["9876", "5555", "1222"], pd.NA, pd.NA, ["2222"]]}

df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)

我们的目标是创建一个名为 valid 的布尔列,其值为 True 当且仅当 col_x 的值等于 col_y 的值,或者 col_x 的值存在于 col_grp 列对应的列表中。

最初尝试使用 df.apply(axis=1) 结合自定义函数可能会遇到 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 错误。这通常是由于在条件判断中不恰当地处理了 pd.NA 或非列表类型数据导致的。例如,直接对 pd.NA 或非列表值进行 in 操作,或在条件判断中使用了Series对象而非标量。为了避免此类问题并提高效率,我们推荐以下两种方法。

方法一:使用列表推导式 (推荐)

对于此类行级操作,Python 的列表推导式通常比 df.apply(axis=1) 更高效,因为它避免了 Pandas 内部的迭代开销,直接利用了 Python 自身的循环机制。通过 zip 函数将多列数据打包,可以方便地进行行级处理。

实现代码:

df['valid_list_comp'] = [x == y or (isinstance(g, list) and x in g)
                         for x, y, g in zip(df['col_x'], df['col_y'], df['col_grp'])]
print("\n使用列表推导式生成'valid_list_comp'列:")
print(df)

代码解析:

ColorMagic
ColorMagic

AI调色板生成工具

下载
  1. zip(df['col_x'], df['col_y'], df['col_grp']): 将 col_x、col_y 和 col_grp 三列的数据按行打包成元组,供列表推导式迭代。
  2. for x, y, g in ...: 每次迭代时,x、y、g 分别对应当前行的 col_x、col_y 和 col_grp 值。
  3. x == y: 检查 col_x 是否等于 col_y。
  4. isinstance(g, list): 这是一个关键的类型检查。它确保只有当 g 确实是一个列表时,才尝试执行 x in g 操作。这巧妙地处理了 pd.NA 值,因为 pd.NA 不是列表,isinstance(pd.NA, list) 会返回 False,从而避免了对非列表类型执行 in 操作可能引发的错误。
  5. x in g: 检查 col_x 的值是否存在于 col_grp 对应的列表中。
  6. or: 两个条件之间是逻辑或关系,满足其一即可。

优点:

  • 高性能: 对于大型数据集,列表推导式通常比 apply 方法快得多。
  • 简洁明了: 代码逻辑清晰,易于理解。
  • 健壮性: isinstance 检查有效地处理了 pd.NA 和非列表类型数据,避免了潜在的运行时错误。

方法二:优化 apply 函数

尽管列表推导式通常更优,但在某些情况下,如果逻辑非常复杂,或者需要利用 apply 提供的其他功能,我们仍然可能需要使用 apply。关键在于如何编写一个健壮且高效的自定义函数。

实现代码:

def check_validity_optimized(row):
    x, y, g = row['col_x'], row['col_y'], row['col_grp'] # 直接解构行数据
    return x == y or (isinstance(g, list) and x in g)

df['valid_apply'] = df.apply(check_validity_optimized, axis=1)
print("\n使用优化后的apply函数生成'valid_apply'列:")
print(df)

代码解析:

  1. x, y, g = row['col_x'], row['col_y'], row['col_grp']: 在函数内部,首先从 row 对象中提取所需的列值。这使得后续的条件判断更加简洁。
  2. return x == y or (isinstance(g, list) and x in g): 这里的逻辑与列表推导式中的逻辑完全相同,同样利用 isinstance 来安全地处理 col_grp 列中的列表和缺失值。

优点:

  • 结构化: 对于非常复杂的行级逻辑,将代码封装在函数中可以提高可读性和维护性。
  • 灵活性: apply 可以与其他 Pandas 功能结合使用,例如在函数内部进行更复杂的数据转换。

与原始 apply 尝试的对比: 原始尝试的 check_validity 函数可能因为 pd.notnull(row["col_grp"]) 后的 else 分支 return row["col_x"] == row["col_grp"] 在 col_grp 既不是列表也不是 pd.NA 的情况下,其行为可能不符合预期,或者在特定Pandas版本下处理 pd.NA 的比较时引发错误。优化后的函数通过 isinstance(g, list) 明确了只有列表类型才进行 in 操作,这使得逻辑更加清晰和安全。

注意事项与性能考量

  1. 数据类型一致性: 确保 col_x 和 col_y 的数据类型一致,以便进行正确的相等比较。如果它们是不同类型(如字符串和整数),可能需要进行类型转换。
  2. pd.NA 与 None: Pandas 中的 pd.NA 是专门用于表示缺失值的,它与 Python 的 None 有所不同。isinstance(pd.NA, list) 返回 False,这使得我们的解决方案能够优雅地处理缺失值。
  3. 性能差异: 对于大规模数据集,列表推导式通常比 apply(axis=1) 快一个数量级。这是因为 apply 在内部会进行一些额外的开销,例如将每一行转换为 Series 对象再传递给函数。因此,在追求性能时,应优先考虑列表推导式或向量化操作。
  4. DataFrame中存储列表: 虽然 Pandas DataFrame 允许在列中存储列表,但这通常会降低某些 Pandas 向量化操作的效率。如果可能,考虑将列表展开为多行(例如使用 explode()),或者在数据预处理阶段处理这些列表,以更好地利用 Pandas 的向量化能力。然而,对于本教程中的特定需求,将列表存储在列中是可行的。

总结

本文介绍了两种在 Pandas DataFrame 中高效生成

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

79

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

32

2026.01.31

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

337

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

224

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

138

2026.02.12

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号