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
,真的取决于你当前的需求和数据的特性。这不像是一个非此即彼的硬性规定,更像是一种策略选择。

Digram
Digram

让Figma更好用的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

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

707

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

625

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

734

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

616

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1234

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

573

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

695

2023.08.11

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

10

2025.12.24

热门下载

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

精品课程

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

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

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

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