2-1 loc与iloc两种叫号方式


文档摘要

2-1 loc与iloc:分诊台的两种叫号方式 本节摘要:loc按标签取数、切片双闭;iloc按位置取数、切片含头不含尾。本节讲清行列联合索引的语法、切片端点差异、以及旧接口ix被废弃的来龙去脉,读完你在任何表上取数都不再靠猜。 承接第01章1-2建立的两套坐标:那时只按行取,本节升级到行列联合叫号。这也是第06章merge前理解"键"的前置课。 行列联合叫号 同样三行,loc用t1:t3、iloc用0:3。端点规则不同、结果一致,这是最容易埋错的地方:loc是双闭区间,iloc遵守Python惯例左闭右开。等哪天索引不再是恰好有序的字符串,两种写法就会取到不同的行。 切片翻车现场 ⚠️ 常见坑:loc的标签切片在普通(非单调)索引上按"出现顺序"截取,结果依赖当前行序。

2-1 loc与iloc:分诊台的两种叫号方式

本节摘要:loc按标签取数、切片双闭;iloc按位置取数、切片含头不含尾。本节讲清行列联合索引的语法、切片端点差异、以及旧接口ix被废弃的来龙去脉,读完你在任何表上取数都不再靠猜。

承接第01章1-2建立的两套坐标:那时只按行取,本节升级到行列联合叫号。这也是第06章merge前理解"键"的前置课。

行列联合叫号

import pandas as pd df = pd.DataFrame({ '门店': ['A', 'B', 'A', 'C', 'A'], '金额': [1280, 960, 1732, 880, 2100], '渠道': ['线上', '线下', '线上', '线上', '线下'], }, index=['t1', 't2', 't3', 't4', 't5']) # loc[行, 列]:挂号条 + 列名 print(df.loc['t3', '金额']) # 1732 print(df.loc['t1':'t3', '金额']) # 切片双闭,t1 t2 t3 都到 # t1 1280 # t2 960 # t3 1732 # Name: 金额, dtype: int64 # iloc[行, 列]:位置 + 位置 print(df.iloc[2, 1]) # 1732 print(df.iloc[0:3, 1]) # 含头不含尾,同样三行 # t1 1280 # t2 960 # t3 1732 # Name: 金额, dtype: int64

同样三行,loc用t1:t3、iloc用0:3。端点规则不同、结果一致,这是最容易埋错的地方:loc是双闭区间,iloc遵守Python惯例左闭右开。等哪天索引不再是恰好有序的字符串,两种写法就会取到不同的行。

切片翻车现场

shuffled = df.loc[['t5', 't1', 't3', 't2', 't4']] # 打乱挂号顺序 # 按标签切片:loc会在"挂号条的实际顺序"上找t1到t3的区间 print(shuffled.loc['t1':'t3'].index.tolist()) # ['t1', 't3', 't2'] # 想按值的排序取,先排序再切 ordered = shuffled.sort_index() print(ordered.loc['t1':'t3'].index.tolist()) # ['t1', 't2', 't3']

⚠️ 常见坑:loc的标签切片在普通(非单调)索引上按"出现顺序"截取,结果依赖当前行序。要么先sort_index,要么改用isin列表。这是"同样的代码今天对明天错"的经典来源。

列侧的花式叫号

# 列也支持切片与列表 print(df.loc[:, '门店':'金额'].columns.tolist()) # ['门店', '金额'] print(df.loc[:, ['金额', '渠道']].columns.tolist()) # ['金额', '渠道'] # 布尔行 + 列列表:分诊最常用组合 mask = df['金额'] > 1000 print(df.loc[mask, ['门店', '金额']]) # 门店 金额 # t1 A 1280 # t3 A 1732 # t5 A 2100 # at与iat:单值取数的提速版 print(df.at['t3', '金额']) # 1732 print(df.iat[2, 1]) # 1732

两套叫号方式的决策图

loc与iloc选用对照

loc与iloc选用对照

废弃的第三种号:ix的教训

老教程里常见df.ix['t3', 1]这种标签位置混写的接口。它在整数索引上无法判断"3"是标签还是位置,Pandas在0.20版正式废弃了它。遇到旧代码里的ix,迁移规则只有两条:数字一律改iloc,其余改loc。这段历史值得知道,因为它解释了为什么现代Pandas坚持"两套坐标绝不混用"的设计。

# 旧代码:df.ix[2, '金额'] —— 报错或行为不定 # 迁移后二选一: print(df.iloc[2, df.columns.get_loc('金额')]) # 位置行 + 列名转位置 print(df.loc[df.index[2], '金额']) # 位置转标签 + 标签列

本节要点回顾

  • loc标签双闭、iloc位置左闭右开,联合索引用中括号内逗号分隔行列
  • 标签切片依赖行序,非单调索引先sort_index再切
  • 布尔行加列列表(df.loc[mask, cols])是分诊最常用姿势
  • at与iat是单值取数的快速通道
  • ix已废弃,迁移口诀:数字归iloc、其余归loc

追问:取数到底是副本还是视图

分诊台的最后一个经典疑问:df.loc[mask]拿到的结果,改了会不会影响原表?答案是别赌。Pandas的返回值有时是视图有时是副本,规则随版本演进,唯一可靠的姿势是:要改子集就显式复制(.copy()),要在原表上改就用一次到位的单个loc表达式读写。链式赋值(先取子集再对子集赋值)是SettingWithCopyWarning的唯一来源,见到警告不要无视,按这两条姿势重写。

subset = df.loc[mask, ['门店', '金额']].copy() # 明确要独立副本 subset['金额'] = subset['金额'] * 0.9 # 改副本,原表不动 # 要改原表:单个loc完成读位与写入 df.loc[mask, '金额'] = df.loc[mask, '金额'] * 0.9

这个话题在第03章的清洗操作里还会高频出现,届时你会庆幸现在把规则立好了。

一个综合演练

把本章器械连起来用一次:从明细里取出"金额前三的大额线上交易"的门店与金额两列。

top = (df[df['渠道'] == '线上'] # 布尔筛症状 .nlargest(3, '金额') # 按金额取前三 .loc[:, ['门店', '金额']] # 按标签取列 .reset_index(drop=True)) # 重排挂号条 print(top)

链式写法读起来就是一句话:筛、排、取列、重排。每一步的输出都是下一步的输入,这正是Pandas流水线的表达力所在。

下一节把叫号升级成按症状筛人:布尔索引。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U