索引界的四大天王:loc
, iloc
, at
, iat
的传奇故事 (附带避坑指南)
各位屏幕前的编程英雄们,大家好!我是你们的老朋友,人称Bug终结者、代码段子手、咖啡因爱好者——程序猿阿豪。今天,咱们不聊那些高深的算法,也不谈那些玄乎的架构,咱们聊聊数据分析师和数据科学家们每天都要打交道的“索引”和“选择数据”。
想象一下,你手握着一个巨大的藏宝图(也就是你的DataFrame),里面埋藏着无数的金币(数据)。但是,藏宝图上密密麻麻的标记让你眼花缭乱,你该如何精准地找到你想要的那部分宝藏呢? 这时候,就需要我们的索引界四大天王闪亮登场了!
没错,他们就是:loc
, iloc
, at
, iat
。 听起来像不像武侠小说里的四大高手? 他们个个身怀绝技,能帮你从DataFrame中精准地提取数据。 但是,江湖险恶,一不小心就会踩到坑。 今天,阿豪就带大家深入了解这四位大侠, 掌握他们的使用方法,从此告别索引报错,成为数据寻宝达人!
第一回:loc
大侠 – 标签索引的王者
loc
大侠,顾名思义,是基于标签(label)进行索引的。 他就像一个经验丰富的向导,熟悉藏宝图上的每一个地名,只要你告诉他地名,他就能准确地带你找到宝藏。
语法:
df.loc[row_label, column_label]
row_label
: 行标签(行的名称或索引值)column_label
: 列标签(列的名称)
实例演示:
假设我们有一个关于学生成绩的DataFrame,如下所示:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '赵六'],
'语文': [80, 90, 75, 85],
'数学': [95, 88, 92, 78],
'英语': [82, 78, 85, 90]}
df = pd.DataFrame(data)
df = df.set_index('姓名') # 将“姓名”列设置为索引
print(df)
输出结果:
语文 数学 英语
姓名
张三 80 95 82
李四 90 88 78
王五 75 92 85
赵六 85 78 90
现在,我们想找到张三的语文成绩,可以这样写:
zhangsan_yuwen = df.loc['张三', '语文']
print(f"张三的语文成绩是:{zhangsan_yuwen}")
输出结果:
张三的语文成绩是:80
是不是很简单? loc
大侠就像一个精准的定位仪,根据你提供的标签,直接找到对应的数据。
更高级的用法:
loc
不仅可以提取单个数据,还可以提取多行、多列,甚至可以进行切片操作!
-
提取多行:
top_students = df.loc[['张三', '李四']] # 提取张三和李四的成绩 print(top_students)
输出结果:
语文 数学 英语 姓名 张三 80 95 82 李四 90 88 78
-
提取多列:
chinese_math = df.loc[:, ['语文', '数学']] # 提取所有学生的语文和数学成绩 print(chinese_math)
输出结果:
语文 数学 姓名 张三 80 95 李四 90 88 王五 75 92 赵六 85 78
-
切片操作:
middle_students = df.loc['李四':'王五'] # 提取李四到王五(包含)的成绩 print(middle_students)
输出结果:
语文 数学 英语 姓名 李四 90 88 78 王五 75 92 85
注意:
loc
的切片操作是包含结束标签的,这一点和Python的列表切片不同!
loc
使用注意事项(避坑指南):
-
标签不存在: 如果你提供的标签在DataFrame中不存在,
loc
会毫不留情地抛出一个KeyError
异常。 所以,在使用loc
之前,一定要确认你的标签是正确的!# 错误的例子 #df.loc['阿豪', '语文'] # 会报错,因为DataFrame中没有名为“阿豪”的行
-
标签类型不一致:
loc
严格按照标签类型进行匹配。 如果你的行索引是字符串类型,而你却用整数进行索引,也会报错。 -
链式索引的坑: 避免使用链式索引,例如
df['语文']['张三']
。 这种写法可能会导致意想不到的错误,而且效率较低。 应该使用loc
直接定位到目标数据。# 错误的例子 #df['语文']['张三'] # 不推荐使用 # 正确的例子 df.loc['张三', '语文']
第二回:iloc
大侠 – 位置索引的隐士
iloc
大侠则是一位隐士高手,他不喜欢抛头露面,只用数字来交流。 他是基于整数位置(integer position)进行索引的,就像一个坐标系统,只要你告诉他横纵坐标,他就能准确地找到对应的数据。
语法:
df.iloc[row_index, column_index]
row_index
: 行索引(整数位置,从0开始)column_index
: 列索引(整数位置,从0开始)
实例演示:
还是用上面的学生成绩DataFrame:
print(df)
输出结果:
语文 数学 英语
姓名
张三 80 95 82
李四 90 88 78
王五 75 92 85
赵六 85 78 90
现在,我们想找到第二行(李四)的第三列(英语)的成绩,可以这样写:
lisi_english = df.iloc[1, 2]
print(f"李四的英语成绩是:{lisi_english}")
输出结果:
李四的英语成绩是:78
更高级的用法:
iloc
同样可以提取多行、多列,以及进行切片操作,用法和 loc
类似,只不过使用的是整数位置。
-
提取多行:
first_two_students = df.iloc[[0, 1]] # 提取第一行和第二行的成绩 print(first_two_students)
输出结果:
语文 数学 英语 姓名 张三 80 95 82 李四 90 88 78
-
提取多列:
first_two_subjects = df.iloc[:, [0, 1]] # 提取所有学生的语文和数学成绩 print(first_two_subjects)
输出结果:
语文 数学 姓名 张三 80 95 李四 90 88 王五 75 92 赵六 85 78
-
切片操作:
middle_students = df.iloc[1:3] # 提取第二行到第四行(不包含)的成绩 print(middle_students)
输出结果:
语文 数学 英语 姓名 李四 90 88 78 王五 75 92 85
注意:
iloc
的切片操作是不包含结束位置的,这一点和Python的列表切片一致!
iloc
使用注意事项(避坑指南):
-
索引越界: 如果你提供的整数位置超出了DataFrame的范围,
iloc
也会毫不留情地抛出一个IndexError
异常。 所以,在使用iloc
之前,一定要确认你的索引没有越界!# 错误的例子 #df.iloc[10, 0] # 会报错,因为DataFrame只有4行
-
索引类型错误:
iloc
只能接受整数作为索引。 如果你使用字符串或者其他类型进行索引,也会报错。 -
与
loc
混淆:iloc
和loc
的区别在于索引方式不同。loc
使用标签索引,而iloc
使用整数位置索引。 一定要分清两者的区别,避免混淆! (阿豪建议:记住i
代表integer
, 这样就不会弄混啦!😄)
第三回:at
大侠 – 极致性能的刺客
at
大侠是一位追求极致性能的刺客。 他只专注于提取单个数据,速度极快,就像一把锋利的匕首,直击目标。
语法:
df.at[row_label, column_label]
row_label
: 行标签column_label
: 列标签
实例演示:
还是用上面的学生成绩DataFrame:
print(df)
输出结果:
语文 数学 英语
姓名
张三 80 95 82
李四 90 88 78
王五 75 92 85
赵六 85 78 90
现在,我们想找到王五的数学成绩,可以这样写:
wangwu_math = df.at['王五', '数学']
print(f"王五的数学成绩是:{wangwu_math}")
输出结果:
王五的数学成绩是:92
at
使用注意事项(避坑指南):
-
只能提取单个数据:
at
只能用于提取单个数据,不能用于提取多行、多列或者进行切片操作。 如果你需要提取多个数据,应该使用loc
或者iloc
。 -
标签不存在: 如果你提供的标签在DataFrame中不存在,
at
会抛出一个KeyError
异常。 -
性能优势:
at
的优势在于性能。 当你需要频繁地提取单个数据时,at
的效率会比loc
略高。
第四回:iat
大侠 – 整数坐标的闪电
iat
大侠是 at
的整数位置版本。 他同样追求极致性能,只专注于根据整数位置提取单个数据,速度如闪电般迅捷。
语法:
df.iat[row_index, column_index]
row_index
: 行索引(整数位置)column_index
: 列索引(整数位置)
实例演示:
还是用上面的学生成绩DataFrame:
print(df)
输出结果:
语文 数学 英语
姓名
张三 80 95 82
李四 90 88 78
王五 75 92 85
赵六 85 78 90
现在,我们想找到第三行(王五)的第二列(数学)的成绩,可以这样写:
wangwu_math = df.iat[2, 1]
print(f"王五的数学成绩是:{wangwu_math}")
输出结果:
王五的数学成绩是:92
iat
使用注意事项(避坑指南):
-
只能提取单个数据:
iat
只能用于提取单个数据,不能用于提取多行、多列或者进行切片操作。 如果你需要提取多个数据,应该使用loc
或者iloc
。 -
索引越界: 如果你提供的整数位置超出了DataFrame的范围,
iat
会抛出一个IndexError
异常。 -
性能优势:
iat
的优势在于性能。 当你需要频繁地根据整数位置提取单个数据时,iat
的效率会比iloc
略高。
总结:四大天王的武功秘籍
为了方便大家记忆,阿豪特意整理了一份四大天王的武功秘籍:
大侠 | 索引方式 | 提取数据范围 | 性能 | 适用场景 |
---|---|---|---|---|
loc |
标签 | 单个/多个/切片 | 较慢 | 根据标签选择数据,灵活性高,常用语根据条件筛选数据。 |
iloc |
整数位置 | 单个/多个/切片 | 较慢 | 根据整数位置选择数据,常用于循环遍历DataFrame。 |
at |
标签 | 单个 | 最快 | 根据标签快速提取单个数据,常用于对性能要求较高的场景。 |
iat |
整数位置 | 单个 | 最快 | 根据整数位置快速提取单个数据,常用于对性能要求较高的场景。 |
选择哪个大侠?
- 如果你知道数据的标签,并且需要灵活地选择数据(单个、多个、切片),那么
loc
是你的首选。 - 如果你只知道数据的整数位置,或者需要循环遍历DataFrame,那么
iloc
是你的最佳选择。 - 如果你需要频繁地提取单个数据,并且对性能要求较高,那么
at
或iat
可以帮你提升效率。
记住: 没有最好的大侠,只有最适合你的大侠!
终章:数据寻宝之旅
掌握了索引界四大天王的武功秘籍,你就可以在数据海洋中自由驰骋,精准地找到你想要的宝藏。 但是,武功再高,也需要勤加练习。 多写代码,多踩坑,多总结,你才能真正掌握这些技能,成为数据寻宝的专家!
希望今天的分享对大家有所帮助。 如果大家觉得有用,请点赞、评论、转发,让更多的朋友受益。 我是程序猿阿豪,我们下期再见! (ง •̀_•́)ง