Pandas中iloc[]和loc[]的实现示例

发布时间:2026/10/8 10:37:09
Pandas中iloc[]和loc[]的实现示例 前言loc和iloc是 pandas 里最核心的两个索引器indexer 但它们的区别常常被一句一个按标签、一个按位置带过真用起来还是踩坑。 这篇把两者的行为差异逐条拆开配可直接推演的示例。它们的定位很明确.loc[]是基于标签的索引器写5会被当作索引里名为 5 的 标签而不是第 5 个位置.iloc[]是纯位置索引器接受 0 到len-1的整数位置。官方文档里对两者都还有补充它们都能接受布尔数组 也都能接受一个可调用对象callable.loc的切片两端都含.iloc的切片含头不含尾。这几条正是误用的重灾区。前提说明pandas 是第三方库本机没有 Python 解释器也没有 pandas 示例无法运行验证只能逐行人工推演。行为细节以 Pandas 官方文档为准。一、用同一张表对比# pandas 1.0import pandas as pddf pd.DataFrame({name: [A, B, C], age: [25, 30, 28]},index[r1, r2, r3],)现在行索引是字符串r1..r3列是name/age。下面逐项对比操作.loc.iloc取一行df.loc[r1]df.iloc[0]取一列df.loc[:, name]df.iloc[:, 0]取一格df.loc[r1, age]df.iloc[0, 1]切片df.loc[r1:r2]含两端df.iloc[0:2]不含尾列表df.loc[[r1, r3]]df.iloc[[0, 2]]看出来了吗df.loc[r1:r2]会取到r1和r2两行 而df.iloc[0:1]只取到位置 0 的那一行。切片端点是否包含是二者最反直觉的差别。另外要留意元组定位df.loc[行, 列]和df.iloc[行, 列]里的两个分量 分别对应行轴和列轴各自遵循自己的标签/位置规则。写df.loc[0, 1]并不会自动把1当成列位置而是当成名为 1 的列标签。二、为什么loc里的数字不是位置如果行索引是整数比如默认的RangeIndex写法看起来一样语义却不同# pandas 1.0df2 pd.DataFrame({v: [10, 20, 30, 40]}) # 索引 0,1,2,3print(df2.loc[2]) # 标签为 2 的那一行 - 30print(df2.iloc[2]) # 位置为 2 的那一行 - 30这里两者碰巧一样因为标签恰好等于位置。但只要索引有偏移差别立刻显现# pandas 1.0df3 df2.copy()df3.index [10, 20, 30, 40]print(df3.loc[30]) # 标签 30 - 值 30print(df3.iloc[2]) # 位置 2 - 也是 30此处巧合print(df3.iloc[30]) # 位置 30 越界抛 IndexError关键结论df.loc[30]找的是索引名为 30的行df.iloc[30]找的是第 31 行。当索引进过set_index或筛选后不连续时 两者绝不能互换。三、布尔数组与可调用对象两者都支持布尔数组# pandas 1.0print(df.loc[df[age] 26, name]) # 布尔 Series 筛行print(df.iloc[[False, True, True], 0]) # 显式布尔列表.loc更常和条件表达式搭配.iloc则偶尔用它做位置掩码。 注意布尔数组长度必须与对应轴一致否则报错。两者也都能接一个可调用对象这一点在链式调用里很有用# pandas 1.0print(df.loc[lambda x: x[age] 26])传进 callable 时参数是当前被索引的对象本身Series或DataFrame 返回的应是可索引的东西布尔序列、标签列表等。四、单值与整行的取舍# pandas 1.0row df.loc[r1] # 返回 Seriesval df.loc[r1, age] # 返回标量 25cols df.loc[:, [name]] # 返回 DataFrame要特别注意返回的是Series还是标量多给一个维度就降一级。 如果只想取一个标量且追求更快可用df.at[r1, age] 位置版对应df.iat[0, 1]。它们的语义就是loc/iloc的单点访问器。五、切片可以越界吗官方文档指出iloc的切片索引器允许越界符合 Python/NumPy 的切片语义 但单个整数索引器越界会报错。也就是说# pandas 1.0print(df.iloc[0:100]) # 允许最多取到表尾不报错print(df.iloc[100]) # 越界抛 IndexError而loc的切片是按标签走的端点标签必须存在否则会KeyError。 这一点常被写成iloc更宽容准确说法是只有切片的越界被允许。六、赋值时为什么要坚持用locloc除了取值更是赋值的正确入口。原因在于 pandas 对视图还是副本 的处理当你先切出一块、再往切出来的东西上写写动的可能是一份临时副本 原表没变在旧版这会触发SettingWithCopyWarning。# pandas 1.0df.loc[df[age] 26, name] X # 一次定位、一次赋值从 pandas 3.0 起写时复制Copy-on-Write成为默认行为SettingWithCopyWarning这个警告本身被移除语义统一为 任何切片都是逻辑副本改切片不影响原对象。所以正确的姿势是在原对象上一次说清楚改哪些行、哪一列然后赋值而不是df[...][...] ...。iloc同样可以赋值位置和标签的规则与取值时一致。七、完整示例# pandas 1.0import pandas as pddef demo() - None:df pd.DataFrame({name: [A, B, C], age: [25, 30, 28]},index[r1, r2, r3],)# 标签定位print(df.loc[r1, name]) # Aprint(df.loc[r1:r2, age]) # r1、r2 两行# 位置定位print(df.iloc[0, 1]) # 25print(df.iloc[0:1, 1]) # 只有位置 0 一行# 布尔与可调用print(df.loc[df[age] 26, name])print(df.iloc[lambda x: [True, False, True]])# 单点访问器print(df.at[r3, age], df.iat[2, 1])if __name__ __main__:demo()常见坑点把loc里的数字当成位置❌ 索引是[10, 20, 30]时写df.loc[2]以为取第 3 行 ✅df.loc[2]找的是名为 2的标签按位置要用df.iloc[2]loc和iloc的切片端点规则记反❌ 以为df.loc[a:c]不含c✅loc切片两端都含iloc切片含头不含尾单列取出来当成 DataFrame❌df.loc[r1, name]得到标量却去调.columns✅ 返回Series还是标量取决于给了一个还是两个维度用iloc做越界的单点访问❌df.iloc[100]想取不到就返回空 ✅ 单个位置越界会IndexError只有切片允许越界布尔数组长度对不上❌df.loc[[True, False], :]而表有 3 行报长度不匹配 ✅ 布尔数组长度必须等于被索引轴的长度loc用不存在的标签做切片❌df.loc[a:zzz]以为会截断到表尾 ✅loc端点标签必须存在否则KeyError链式赋值❌df.loc[df[age] 26][name] X旧版报警告、新版可能无效 ✅ 一次定位一次赋值df.loc[df[age] 26, name] X把两者混在同一行里❌df.loc[0, 1]以为第 0 行第 1 列其实两个参数都按标签解释 ✅ 位置一律iloc标签一律loc一行里别混用总结维度.loc.iloc依据标签label整数位置position数字当作标签当作位置切片两端都含含头不含尾越界切片标签须存在允许越界布尔/可调用支持支持单点版.at.iat判断该用哪个只需问自己一句我手上的是标签还是序号 标签用loc序号用iloc永不互换。再记住loc切片两端都含、iloc切片含头不含尾这一条绝大多数索引困惑就能当场解开。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询