0

0

Pandas DataFrame 高效批量设置指定单元格值教程

DDD

DDD

发布时间:2025-12-02 09:01:23

|

305人浏览过

|

来源于php中文网

原创

pandas dataframe 高效批量设置指定单元格值教程

在处理大型Pandas DataFrame时,迭代式地为特定单元格赋值效率低下。本文将深入探讨如何利用Pandas底层NumPy数组的高级索引能力,通过将DataFrame的行标签和列标签转换为其对应的整数位置索引,从而实现对DataFrame中多个指定位置进行高效、非迭代的批量赋值操作,显著提升数据处理性能。

引言:Pandas DataFrame 批量赋值的性能挑战

在数据分析和处理中,我们经常需要更新Pandas DataFrame中的特定单元格。一个常见的场景是,我们有一个需要更新的行标签和列标签列表,希望将这些特定交叉点的值设置为某个预设值。然而,对于大型DataFrame而言,采用传统的Python for 循环逐一赋值的方式,其性能开销是巨大的,可能导致程序运行缓慢。

考虑以下示例,我们尝试通过循环为DataFrame中的1000个随机位置赋值:

import pandas as pd
import numpy as np

# 创建一个大型DataFrame
column_names = np.array(range(100))
np.random.shuffle(column_names)
row_names = np.array(range(100))
np.random.shuffle(row_names)
df = pd.DataFrame(columns=column_names, index=row_names)

# 生成需要赋值的索引位置(标签)
ix_labels = np.random.randint(0, 100, 1000)
iy_labels = np.random.randint(0, 100, 1000)

# 方式一:逐个循环赋值 (效率低下)
# for k in range(len(ix_labels)):
#     df.loc[ix_labels[k], iy_labels[k]] = 1
# 此操作对于1000次赋值可能需要数百毫秒甚至更长时间

这种迭代方法在数据量增大时,性能瓶颈会非常明显。

常见的误区:df.loc[ix, iy] = value 的局限性

有些开发者可能会尝试使用Pandas的标签索引器 loc 进行批量赋值,例如:

# 方式二:尝试使用 df.loc[ix, iy] = 1 (不适用于指定配对)
# df.loc[ix_labels, iy_labels] = 1

然而,这种方法并不能实现我们期望的“为特定 (行标签, 列标签) 对赋值”的效果。df.loc[ix_labels, iy_labels] = 1 会将 ix_labels 中所有行标签与 iy_labels 中所有列标签的笛卡尔积所形成的单元格都设置为1。这意味着,如果 ix_labels 和 iy_labels 各有 N 个元素,那么 N*N 个单元格会被赋值,而非我们希望的 N 个特定配对单元格。这显然不符合我们的需求,并且可能错误地修改大量不相关的单元格。

解决方案:利用NumPy底层数组的高级索引进行高效赋值

要实现高效地为多个指定配对的单元格赋值,我们需要绕过Pandas的标签索引系统,直接操作其底层的NumPy数组。NumPy数组支持高级索引(Advanced Indexing),允许我们通过两个整数数组来指定需要赋值的精确 (行位置, 列位置) 对。

Unscreen
Unscreen

AI智能视频背景移除工具

下载

关键在于如何将Pandas DataFrame的行标签和列标签转换为它们在底层NumPy数组中的整数位置。这可以通过创建映射Series来实现。

核心步骤:

  1. 创建标签到位置的映射:
    • 将DataFrame的行标签映射到其对应的行整数位置(0到df.shape[0]-1)。
    • 将DataFrame的列标签映射到其对应的列整数位置(0到df.shape[1]-1)。
  2. 获取目标标签的位置索引:
    • 使用 .reindex() 方法,根据需要赋值的行标签列表和列标签列表,从上述映射中获取它们对应的整数位置数组。
  3. 直接操作底层NumPy数组:
    • 通过 df.values 访问DataFrame的底层NumPy数组。
    • 使用步骤2中得到的整数位置数组进行高级索引,并进行批量赋值。

示例代码:

import pandas as pd
import numpy as np
import time

# 准备一个DataFrame
df = pd.DataFrame(index=['a', 'b', 'c', 'd', 'e'],
                  columns=['A', 'B', 'C', 'D', 'E'])

# 需要赋值的行标签和列标签列表
# 例如,我们要将 ('a', 'A'), ('b', 'C'), ('c', 'A'), ('e', 'D') 设置为1
ix_to_set = ['a', 'b', 'c', 'e']
iy_to_set = ['A', 'C', 'A', 'D']

# 1. 创建标签到位置的映射
# 将列标签映射到其整数位置
cols_map = pd.Series(range(df.shape[1]), index=df.columns)
# 将行标签映射到其整数位置
idx_map = pd.Series(range(df.shape[0]), index=df.index)

# 2. 获取目标标签的位置索引
# 根据ix_to_set获取对应的行位置索引
row_positions = idx_map.reindex(ix_to_set).values
# 根据iy_to_set获取对应的列位置索引
col_positions = cols_map.reindex(iy_to_set).values

# 3. 直接操作底层NumPy数组进行赋值
# 确保位置索引是整数类型,以避免可能的警告或错误
df.values[row_positions.astype(int), col_positions.astype(int)] = 1

print("赋值后的DataFrame:")
print(df)

输出结果:

赋值后的DataFrame:
     A    B    C    D    E
a  1.0  NaN  NaN  NaN  NaN
b  NaN  NaN  1.0  NaN  NaN
c  1.0  NaN  NaN  NaN  NaN
d  NaN  NaN  NaN  NaN  NaN
e  NaN  NaN  NaN  1.0  NaN

从输出可以看出,只有我们指定的 ('a', 'A'), ('b', 'C'), ('c', 'A'), ('e', 'D') 这四个单元格被成功地设置为了1,其余单元格保持不变。

性能对比与注意事项

使用这种方法,其性能远超循环赋值。在最初的1000次随机赋值的例子中,循环赋值可能需要0.35秒,而通过NumPy高级索引的方式可能仅需0.035秒,性能提升高达10倍。

注意事项:

  • 标签必须存在: reindex() 方法在找不到对应标签时会返回 NaN。如果 ix_to_set 或 iy_to_set 中包含DataFrame中不存在的标签,reindex 会返回 NaN,然后 astype(int) 会报错。因此,在使用前,请确保所有目标标签都存在于DataFrame的索引或列中。如果可能存在缺失标签,需要额外处理,例如过滤掉这些标签或使用 fillna() 替换 NaN。
  • 数据类型: df.values 返回的是底层NumPy数组的视图。直接修改 df.values 会影响原始DataFrame。如果DataFrame的数据类型是混合的,df.values 可能会返回 object 类型数组。在赋值时,NumPy会自动尝试进行类型转换。
  • 索引的顺序: ix_to_set 和 iy_to_set 必须是对应关系,即 ix_to_set[k] 和 iy_to_set[k] 组成一个需要赋值的单元格。

总结

当需要在Pandas DataFrame中批量更新多个特定配对的单元格时,应避免使用低效的 for 循环迭代。通过将DataFrame的标签(索引和列名)映射到其整数位置,并利用 df.values 访问底层NumPy数组进行高级索引赋值,可以显著提升操作效率。这种方法是处理大规模数据更新场景下的专业且高效的解决方案。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

78

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

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

611

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

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号