You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效通过列名和行索引(行号)选取Pandas DataFrame值并优化代码

高效处理Pandas DataFrame:取值方法与逐行计算优化

一、正确通过列名和行索引选取DataFrame的值

Pandas针对**标签索引(行/列的名称)和位置索引(行/列的序号,从0开始)**提供了两种核心取值方式,搞清楚它们的区别就能避免踩坑:

  • 按标签选取(loc):专门用于通过行名和列名定位数据,语法为 df.loc[行标签, 列标签]

    • 示例:选取行标签为'user_001'、列名为'target'的值:dataset.loc['user_001', 'target']
    • 要选取整行/整列,用:代替对应部分即可:dataset.loc['user_001', :](整行)、dataset.loc[:, 'target'](整列)
  • 按位置选取(iloc):通过行号和列号定位数据,语法为 df.iloc[行号, 列号]

    • 示例:选取第5行(索引4)、第3列(索引2)的值:dataset.iloc[4, 2]
    • 同样支持:选取整行/整列:dataset.iloc[4, :](第5行)、dataset.iloc[:, 2](第3列)
  • 快速单值选取:如果仅需获取单个值,at(标签)和iat(位置)比loc/iloc更高效——它们跳过了额外的校验逻辑:

    • dataset.at['user_001', 'target']、dataset.iat[4, 2]

二、高效解决逐行计算的性能与警告问题

你的原始循环代码存在两个核心痛点:

  1. 逐行迭代效率极低:Pandas是为向量化操作设计的,Python级别的循环会极大拖慢速度,且反复创建临时对象会占用大量内存,完全不适合Web应用的高并发场景。
  2. SettingWithCopy警告:直接通过dataset.target[i]修改值时,你可能在操作DataFrame的切片副本而非原数据,这会导致警告和潜在的数据不一致。

而你尝试的iloc[i, :].loc[...]代码无法生效,是因为iloc[i, :]返回的是该行的Series副本,修改副本不会同步到原DataFrame。

优化方案:用向量化操作替代循环

下面两种方案完全适配Web应用的高效、低内存需求,速度是循环的几十到几百倍:

方法1:布尔索引批量赋值

import pandas as pd

# 先初始化两列为0
dataset['sum_lost'] = 0
dataset['ratio_lost'] = 0

# 筛选出target为1的行的布尔标记
mask = dataset['target'] == 1

# 批量计算并赋值sum_lost
dataset.loc[mask, 'sum_lost'] = dataset.loc[mask, 'to_be_repaid_principal'] + dataset.loc[mask, 'to_be_repaid_interest']

# 批量计算并赋值ratio_lost(若存在除以0风险,可加判断:dataset.loc[mask & (dataset['expected_returned_sum'] != 0), ...])
dataset.loc[mask, 'ratio_lost'] = dataset.loc[mask, 'sum_lost'] / dataset.loc[mask, 'expected_returned_sum']

方法2:np.where简化逻辑

import numpy as np

# 一行搞定sum_lost的赋值:target为1时取两列之和,否则为0
dataset['sum_lost'] = np.where(
    dataset['target'] == 1,
    dataset['to_be_repaid_principal'] + dataset['to_be_repaid_interest'],
    0
)

# 同样一行搞定ratio_lost
dataset['ratio_lost'] = np.where(
    dataset['target'] == 1,
    dataset['sum_lost'] / dataset['expected_returned_sum'],
    0
)

为什么这些方案更优?

  • 速度爆炸提升:向量化操作是在C语言级别执行的,完全避开了Python循环的性能瓶颈。
  • 内存占用极低:无需创建大量临时Series对象,内存消耗仅为循环方案的几分之一。
  • 彻底消除警告:通过loc[mask, ...]直接操作原DataFrame的指定行和列,不存在副本修改的问题。

如果你的Web应用需要处理超大规模数据集,还可以考虑用Dask做并行处理,但对于绝大多数场景,上面的向量化方案已经足够高效。

内容的提问来源于stack exchange,提问作者Dominik Novotný

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:37:46