0

0

python中pandas的loc和iloc有什么区别?

冰火之心

冰火之心

发布时间:2025-09-12 12:48:02

|

719人浏览过

|

来源于php中文网

原创

loc基于标签选择数据,iloc基于整数位置;前者切片包含结束值,适用于有业务含义的索引,后者切片不包含结束值,适合按位置批量操作。

python中pandas的loc和iloc有什么区别?

Pandas中的

loc
iloc
都是用于数据选择的强大工具,但它们的根本区别在于
loc
是基于标签(label-based)进行选择的,而
iloc
则是基于整数位置(integer-location based)进行选择。简单来说,如果你想通过行名和列名来选取数据,就用
loc
;如果你想通过行号和列号(就像Python列表的索引一样)来选取,那就用
iloc
。理解这一点,能帮你避开很多在使用Pandas时可能遇到的坑。

解决方案

要深入理解

loc
iloc
,最好的办法就是看它们在不同场景下的具体行为。它们就像是Pandas数据框的两把不同钥匙,分别对应不同的锁。

loc
:基于标签的选择

loc
操作符主要通过行索引标签和列名来选取数据。它的语法是
df.loc[行标签, 列标签]
。这里有几个关键点:

立即学习Python免费学习笔记(深入)”;

  • 行标签和列标签可以是单个值,也可以是列表。 比如,
    df.loc['row_label_1', 'col_A']
    或者
    df.loc[['row_label_1', 'row_label_2'], ['col_A', 'col_B']]
  • 切片操作是包含结束值的。 这一点和Python原生的切片(不包含结束值)非常不同。如果你写
    df.loc['start_label':'end_label']
    ,那么
    end_label
    对应的那一行数据也会被包含在结果中。
  • 布尔索引。
    loc
    非常适合结合布尔条件进行筛选,例如
    df.loc[df['col_A'] > 10]
    会返回
    col_A
    列值大于10的所有行。

举个例子:

import pandas as pd
import numpy as np

# 创建一个带有自定义索引和列名的数据框
data = {
    'A': [10, 20, 30, 40, 50],
    'B': [1, 2, 3, 4, 5],
    'C': [100, 200, 300, 400, 500]
}
index_labels = ['r1', 'r2', 'r3', 'r4', 'r5']
df = pd.DataFrame(data, index=index_labels)
print("原始DataFrame:\n", df)

# 1. 选择单行单列
print("\nloc: 选择'r2'行和'B'列:\n", df.loc['r2', 'B']) # 输出:2

# 2. 选择多行多列
print("\nloc: 选择'r1'到'r3'行和'A'到'C'列:\n", df.loc['r1':'r3', 'A':'C'])
# 注意,'r3'和'C'都被包含在内

# 3. 使用布尔索引
print("\nloc: 选择'A'列大于20的所有行:\n", df.loc[df['A'] > 20])

iloc
:基于整数位置的选择

iloc
操作符则完全依赖于数据的整数位置,和Python列表的索引方式一模一样。它的语法是
df.iloc[行位置, 列位置]

  • 行位置和列位置都是从0开始的整数。 负数索引也有效,例如-1表示最后一行或最后一列。
  • 切片操作是不包含结束值的。 这和Python原生的切片行为一致。
    df.iloc[0:3]
    会选择第0、1、2行,不包含第3行。
  • 不支持布尔索引。
    iloc
    不能直接接受布尔数组作为索引,因为它只认整数位置。

继续上面的例子:

# 1. 选择单行单列
print("\niloc: 选择第1行(索引为0)和第2列(索引为1):\n", df.iloc[0, 1]) # 输出:10 (df.iloc[0,1] 对应 'r1', 'B')

# 2. 选择多行多列
print("\niloc: 选择第0到2行(不包含第3行)和第0到1列(不包含第2列):\n", df.iloc[0:3, 0:2])
# 对应 'r1', 'r2', 'r3' 行 和 'A', 'B' 列

# 3. 使用负数索引
print("\niloc: 选择最后一行和最后一列:\n", df.iloc[-1, -1]) # 输出:500

我个人觉得,当你拿到一个新数据集,想快速预览前几行或者某个特定位置的数据时,

iloc
会更顺手。但如果你在做报表或者处理有明确业务含义的列名和行索引的数据,
loc
的表达力会强得多,也更不容易出错。

为什么
loc
iloc
在处理非默认整数索引时表现不同?

这确实是很多初学者会感到困惑的地方,我自己也曾在这里栽过跟头。问题核心在于,当你的DataFrame索引本身就是整数时,比如

0, 1, 2, ...
loc
iloc
看起来似乎能达到同样的效果,但这只是表象。一旦你的索引不是默认的
0, 1, 2, ...
,或者你故意将索引设置为非连续的整数,甚至重复的整数,它们的行为差异就会立刻显现出来。

loc
始终将你传入的数字视为标签。如果你的DataFrame索引是
[10, 20, 30]
,那么
df.loc[20]
会去寻找标签为
20
的那一行。而
iloc
则始终将你传入的数字视为位置
df.iloc[2]
会去寻找DataFrame中的第3行(因为是从0开始计数)。

来看一个具体的例子,这能更好地说明问题:

data_custom_index = {
    'Value': [100, 200, 300, 400]
}
custom_index = [1, 3, 5, 7] # 自定义整数索引
df_custom = pd.DataFrame(data_custom_index, index=custom_index)
print("带有自定义整数索引的DataFrame:\n", df_custom)

# 尝试用loc和iloc选择
print("\ndf_custom.loc[3]:\n", df_custom.loc[3]) # 选择标签为3的行
# print(df_custom.loc[2]) # 这一行会报错,因为没有标签为2的行

print("\ndf_custom.iloc[1]:\n", df_custom.iloc[1]) # 选择位置为1(即第二行)的行

# 看看它们的不同
print("\ndf_custom.loc[3]['Value']:", df_custom.loc[3]['Value']) # 输出 200
print("df_custom.iloc[1]['Value']:", df_custom.iloc[1]['Value']) # 输出 200

# 结果一样是因为碰巧了,但它们的逻辑完全不同
# 如果我们想取第0行的值(标签为1)
print("\ndf_custom.loc[1]['Value']:", df_custom.loc[1]['Value']) # 输出 100
print("df_custom.iloc[0]['Value']:", df_custom.iloc[0]['Value']) # 输出 100

# 重点来了:
# 如果我想要取标签为 5 的那一行,我用 loc[5]
print("\nloc选择标签为5的行:\n", df_custom.loc[5])

# 如果我想要取第 2 个位置(从0开始计数,也就是第三行)的那一行,我用 iloc[2]
print("\niloc选择位置为2的行:\n", df_custom.iloc[2])

# 它们在数值上是等价的,但概念上完全不同。
# loc 找的是索引值等于 5 的那一行,而 iloc 找的是 DataFrame 内部存储顺序上的第三行。

这种区别在数据被重新排序后尤为明显。如果你的DataFrame被排序了,

iloc
仍然会按照新的物理顺序来取数据,而
loc
则会根据标签找到它最初对应的那一行,无论它现在在物理上处于哪个位置。在我看来,这是理解两者最核心的钥匙。

在实际数据分析中,我应该如何选择使用
loc
还是
iloc

选择

loc
还是
iloc
,真的取决于你当前的需求和数据的特性。这不像是一个非此即彼的硬性规定,更像是一种策略选择。

WPS AI
WPS AI

金山办公发布的AI办公应用,提供智能文档写作、阅读理解和问答、智能人机交互的能力。

下载
  • 当你的索引有明确的业务含义时,坚决使用
    loc
    比如,你的DataFrame索引是日期、用户ID、产品SKU等。使用
    loc
    能让你的代码更具可读性,也更健壮。即使数据顺序被打乱,
    loc
    也能准确地找到你想要的数据,因为它依赖的是标签而不是物理位置。想象一下,你有一个按日期索引的销售数据,你想查看2023年10月15日的数据,写
    df.loc['2023-10-15']
    比去算它是第几行要直观和安全得多。
  • 当你需要基于位置进行批量操作时,
    iloc
    是首选。
    比如,你只想处理前10行数据,或者去除最后两列。这时候,
    iloc
    的简洁性就体现出来了。
    df.iloc[0:10]
    或者
    df.iloc[:, :-2]
    这种写法,既清晰又高效。在进行数据清洗或特征工程时,经常需要这种基于位置的批量处理。
  • 进行布尔索引筛选时,通常与
    loc
    结合使用。
    虽然布尔数组本身可以直接作为索引,但当你想在筛选的同时也指定列时,
    loc
    的优势就出来了。例如,
    df.loc[df['Sales'] > 1000, ['Product', 'Price']]
    这种组合非常强大,它能帮你精确地定位到满足特定条件的行和特定的列。
  • 如果你需要对数据进行迭代,或者在循环中按顺序处理数据,
    iloc
    可能更合适。
    比如,你可能需要遍历DataFrame的每一行,或者每隔N行取一次数据。在这种场景下,基于整数位置的
    iloc
    会让你写出更简洁的循环逻辑。

我个人的经验是,在大部分业务分析场景下,我会倾向于使用

loc
。因为数据往往带有丰富的语义信息,利用这些标签能让代码更“说人话”,也更不容易因数据结构变化而失效。只有在确实需要操作数据物理位置,或者进行一些通用性的数据切片时,我才会转向
iloc
。两者结合使用,才是Pandas数据选择的真正艺术。

使用
loc
iloc
时有哪些常见的陷阱和最佳实践?

即便你已经理解了

loc
iloc
的基本区别,在使用过程中还是有一些“坑”需要注意,以及一些能让你的代码更健壮、更高效的最佳实践。

常见陷阱:

  1. 切片行为的差异: 这是最常见的陷阱之一。

    • loc
      的切片是包含结束标签的。
      df.loc['A':'C']
      会包含'A'、'B'、'C'三行(如果它们存在)。
    • iloc
      的切片是不包含结束位置的。
      df.iloc[0:3]
      会包含第0、1、2行,不包含第3行。 这种不一致性经常让人犯错,尤其是在从Python列表操作习惯过渡到Pandas时。
  2. SettingWithCopyWarning
    这是一个让无数Pandas用户头疼的问题。当你通过链式索引(例如
    df['col_A'][df['col_B'] > 10] = value
    )来修改DataFrame时,Pandas可能会发出这个警告。它告诉你,你可能正在修改一个副本,而不是原始DataFrame的视图,导致你的修改没有实际反映到原始数据上。

    • 解决方案: 始终使用
      loc
      iloc
      进行链式赋值操作,并确保它们是单次操作。例如,
      df.loc[df['col_B'] > 10, 'col_A'] = value
      。这能明确告诉Pandas你想要修改原始DataFrame的特定部分。如果实在需要修改一个副本,就明确地使用
      .copy()
  3. 整数索引的模糊性: 当DataFrame的索引恰好是

    0, 1, 2, ...
    这样的整数时,
    df.loc[0]
    df.iloc[0]
    都会返回第一行。这会给人一种错觉,认为它们是等价的。然而,一旦你改变了索引,或者索引不再是连续的整数,这种等价性就会立刻消失。我见过太多人因此而写出在特定数据集上能跑,换个数据集就崩溃的代码。

  4. 单元素选择返回Series: 当你使用

    loc
    iloc
    选择单行或单列时,Pandas默认会返回一个Series。如果你期望得到一个DataFrame,可能需要进行额外的处理,例如使用
    df.loc[['label']]
    (注意双层列表)来确保返回的是一个DataFrame。

最佳实践:

  1. 优先使用

    loc
    处理带有业务含义的索引和列名。 这不仅能提高代码的可读性,还能增加代码的健壮性。你的代码会更清楚地表达“我要选择销售额大于1000的客户的姓名和地址”,而不是“我要选择满足某个条件的第0列和第2列”。

  2. 明确指定行和列。 即使你只想选择所有行或所有列,也建议明确使用

    :
    。例如,
    df.loc[:, 'col_A']
    df['col_A']
    更明确地表达了你是在使用
    loc
    的行/列选择语法。

  3. 避免链式索引进行赋值。 这一点和

    SettingWithCopyWarning
    紧密相关。总是尝试将选择和赋值操作合并到一次
    loc
    iloc
    调用中。

  4. 理解你的索引。 在处理数据之前,花点时间检查DataFrame的索引类型和内容。

    df.index
    df.columns
    是你最好的朋友。了解你的索引是标签还是位置,能帮你避免很多不必要的错误。

  5. 在需要时使用

    .copy()
    如果你确实需要创建一个DataFrame的独立副本进行操作,而不是修改原始数据,请务必使用
    .copy()
    。例如,
    df_copy = df.loc[df['col_A'] > 10].copy()
    。这能明确你的意图,并避免潜在的副作用。

通过遵循这些原则,你不仅能更有效地利用

loc
iloc
,还能写出更清晰、更可靠的Pandas代码,这在复杂的数据分析项目中是至关重要的。

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

67

2025.12.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

539

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

21

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

28

2026.01.06

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

location.assign
location.assign

在前端开发中,我们经常需要使用JavaScript来控制页面的跳转和数据的传递。location.assign就是JavaScript中常用的一个跳转方法。通过location.assign,我们可以在当前窗口或者iframe中加载一个新的URL地址,并且可以保存旧页面的历史记录。php中文网为大家带来了location.assign的相关知识、以及相关文章等内容,供大家免费下载使用。

226

2023.06.27

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

0

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

0

2026.01.30

热门下载

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

精品课程

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

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

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

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