各位亲爱的编程冒险家们,晚上好!欢迎来到“索引与选择数据:loc
, iloc
, at
, iat
的奇幻漂流”讲座现场!我是今晚的船长,哦不,是讲师,名叫“数据老司机”。今天,咱们不聊枯燥的语法,不背生硬的公式,而是要一起扬帆起航,探索 Pandas 库中索引与选择数据的那些事儿,让 loc
, iloc
, at
, iat
这四位“护法”助你披荆斩棘,在数据的大海上乘风破浪!
准备好了吗?让我们解开缆绳,起航喽! 🚢
第一章:索引的艺术,犹如寻宝的地图
想象一下,数据就像一座埋藏着宝藏的小岛,而索引就是指引你找到宝藏的地图。没有地图,你只能像无头苍蝇一样乱撞,最终空手而归。在 Pandas 中,索引就是定位和访问数据的关键。
Pandas 提供了两种主要的索引方式:
- 标签索引 (Label-based Indexing): 使用行或列的标签(名称)来定位数据。就像在地图上查找“海盗湾”一样,你知道明确的目标地点。
- 位置索引 (Integer-based Indexing): 使用行或列的整数位置来定位数据。就像在地图上查找“东经120度,北纬30度”一样,你知道具体的坐标。
明白了吧?标签索引是“指名道姓”,位置索引是“按图索骥”。
第二章:四大护法登场:loc
, iloc
, at
, iat
现在,让我们隆重介绍今晚的主角,四位身怀绝技的“护法”:
loc
(Location): 标签索引的守护者,认标签不认人(位置)。iloc
(Integer Location): 位置索引的忠实拥趸,认位置不认标签。at
(Access at Label):loc
的精简版,专攻单个元素的标签索引,速度更快。iat
(Access at Integer Location):iloc
的精简版,专攻单个元素的位置索引,同样追求速度。
可以把 loc
和 iloc
看作是“全能选手”,既可以访问单个元素,也可以访问数据切片。而 at
和 iat
则是“短跑健将”,只擅长访问单个元素,但速度更快,更适合对性能有要求的场景。
第三章:loc
护法:标签索引的王者
loc
护法是标签索引的专家,它只认标签,不认位置。想象一下,你手里拿着一张写着“幸福大街1号”的纸条,loc
护法会帮你找到“幸福大街1号”对应的房子,而不会管它是这条街上的第几栋房子。
语法:
dataframe.loc[row_label, column_label]
其中:
row_label
: 行标签,可以是单个标签、标签列表或标签切片。column_label
: 列标签,可以是单个标签、标签列表或标签切片。
举个栗子 🌰:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 28, 32],
'城市': ['北京', '上海', '广州', '深圳']}
df = pd.DataFrame(data, index=['A', 'B', 'C', 'D']) # 自定义索引
print(df)
# 输出:
# 姓名 年龄 城市
# A 张三 25 北京
# B 李四 30 上海
# C 王五 28 广州
# D 赵六 32 深圳
# 1. 访问单行数据:
print(df.loc['B'])
# 输出:
# 姓名 李四
# 年龄 30
# 城市 上海
# Name: B, dtype: object
# 2. 访问单列数据:
print(df.loc[:, '年龄']) # 访问所有行的 '年龄' 列
# 输出:
# A 25
# B 30
# C 28
# D 32
# Name: 年龄, dtype: int64
# 3. 访问特定行和列的数据:
print(df.loc['C', '城市']) # 访问 'C' 行的 '城市' 列
# 输出:
# 广州
# 4. 使用标签切片:
print(df.loc['B':'D', '姓名':'城市']) # 访问 'B' 到 'D' 行,'姓名' 到 '城市' 列
# 输出:
# 姓名 年龄 城市
# B 李四 30 上海
# C 王五 28 广州
# D 赵六 32 深圳
# 5. 使用标签列表:
print(df.loc[['A', 'C'], ['姓名', '年龄']]) # 访问 'A' 和 'C' 行的 '姓名' 和 '年龄' 列
# 输出:
# 姓名 年龄
# A 张三 25
# C 王五 28
# 6. 使用布尔索引 (Boolean Indexing):
print(df.loc[df['年龄'] > 28]) # 访问年龄大于 28 的行
# 输出:
# 姓名 年龄 城市
# B 李四 30 上海
# D 赵六 32 深圳
注意事项:
- 在使用标签切片时,
loc
包含切片的结束标签 (inclusive)。 - 如果使用的标签不存在,
loc
会抛出KeyError
异常。
第四章:iloc
护法:位置索引的先锋
iloc
护法是位置索引的专家,它只认位置,不认标签。想象一下,你手里拿着一张写着“第 3 排,第 2 个座位”的票,iloc
护法会帮你找到电影院里第 3 排的第 2 个座位,而不会管这个座位上写着什么名字。
语法:
dataframe.iloc[row_position, column_position]
其中:
row_position
: 行位置,可以是单个整数、整数列表或整数切片。column_position
: 列位置,可以是单个整数、整数列表或整数切片。
举个栗子 🌰:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 28, 32],
'城市': ['北京', '上海', '广州', '深圳']}
df = pd.DataFrame(data) # 使用默认整数索引
print(df)
# 输出:
# 姓名 年龄 城市
# 0 张三 25 北京
# 1 李四 30 上海
# 2 王五 28 广州
# 3 赵六 32 深圳
# 1. 访问单行数据:
print(df.iloc[1]) # 访问第 1 行(索引为 1)
# 输出:
# 姓名 李四
# 年龄 30
# 城市 上海
# Name: 1, dtype: object
# 2. 访问单列数据:
print(df.iloc[:, 1]) # 访问所有行的第 1 列(索引为 1)
# 输出:
# 0 25
# 1 30
# 2 28
# 3 32
# Name: 年龄, dtype: int64
# 3. 访问特定行和列的数据:
print(df.iloc[2, 0]) # 访问第 2 行的第 0 列
# 输出:
# 王五
# 4. 使用整数切片:
print(df.iloc[1:3, 0:2]) # 访问第 1 到 2 行,第 0 到 1 列
# 输出:
# 姓名 年龄
# 1 李四 30
# 2 王五 28
# 5. 使用整数列表:
print(df.iloc[[0, 2], [0, 2]]) # 访问第 0 和 2 行的第 0 和 2 列
# 输出:
# 姓名 城市
# 0 张三 北京
# 2 王五 广州
注意事项:
- 在使用整数切片时,
iloc
不包含切片的结束位置 (exclusive)。 - 如果使用的位置超出范围,
iloc
会抛出IndexError
异常。
第五章:at
和 iat
护法:速度的化身
at
和 iat
护法是 loc
和 iloc
的精简版,它们只用于访问单个元素,但速度更快。它们就像数据访问领域的“闪电侠”,能够在眨眼间找到目标。
语法:
dataframe.at[row_label, column_label] # 基于标签
dataframe.iat[row_position, column_position] # 基于位置
举个栗子 🌰:
import pandas as pd
data = {'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 28, 32],
'城市': ['北京', '上海', '广州', '深圳']}
df = pd.DataFrame(data, index=['A', 'B', 'C', 'D'])
# 使用 at 访问单个元素:
print(df.at['B', '年龄']) # 访问 'B' 行的 '年龄' 列
# 输出:
# 30
# 使用 iat 访问单个元素:
print(df.iat[2, 0]) # 访问第 2 行的第 0 列
# 输出:
# 王五
何时使用 at
和 iat
?
当需要频繁访问 DataFrame 中的单个元素时,例如在循环中,使用 at
和 iat
可以显著提高性能。
第六章:实战演练:数据分析小案例
让我们用一个实际的例子来巩固一下所学知识。假设我们有一个销售数据表,记录了不同产品的销售额。
import pandas as pd
sales_data = {'产品': ['A', 'B', 'C', 'D', 'E'],
'地区': ['北京', '上海', '广州', '深圳', '北京'],
'销售额': [100, 150, 80, 120, 90]}
df_sales = pd.DataFrame(sales_data)
print(df_sales)
# 输出:
# 产品 地区 销售额
# 0 A 北京 100
# 1 B 上海 150
# 2 C 广州 80
# 3 D 深圳 120
# 4 E 北京 90
# 1. 找到上海地区的销售额:
shanghai_sales = df_sales.loc[df_sales['地区'] == '上海', '销售额'].values[0] # 使用 .values[0] 获取单个值
print(f"上海地区的销售额: {shanghai_sales}")
# 2. 找到销量最高的产品的名称:
max_sales_product = df_sales.loc[df_sales['销售额'] == df_sales['销售额'].max(), '产品'].values[0]
print(f"销量最高的产品: {max_sales_product}")
# 3. 将北京地区的销售额增加 10%:
df_sales.loc[df_sales['地区'] == '北京', '销售额'] = df_sales.loc[df_sales['地区'] == '北京', '销售额'] * 1.1
print(df_sales)
第七章:总结与注意事项
恭喜各位,我们已经完成了这次索引与选择数据的奇幻漂流!让我们来回顾一下今天学到的知识:
loc
: 标签索引,认标签不认位置。iloc
: 位置索引,认位置不认标签。at
:loc
的精简版,访问单个元素,速度更快。iat
:iloc
的精简版,访问单个元素,速度更快。
注意事项:
- 明确你的目标:你是想基于标签索引,还是基于位置索引?
- 区分切片:
loc
包含结束标签,iloc
不包含结束位置。 - 处理异常:注意
KeyError
和IndexError
异常。 - 性能优化:在频繁访问单个元素时,考虑使用
at
和iat
。 - 灵活运用布尔索引,可以进行更复杂的数据筛选。
表格总结:
方法 | 索引类型 | 访问对象 | 切片包含结束值 | 速度 |
---|---|---|---|---|
loc |
标签 | 行、列 | 是 | 较慢 |
iloc |
位置 | 行、列 | 否 | 较慢 |
at |
标签 | 单个元素 | N/A | 快 |
iat |
位置 | 单个元素 | N/A | 快 |
希望今天的讲座能够帮助大家更好地掌握 Pandas 中索引与选择数据的技巧。记住,熟能生巧,多多练习,你也能成为数据分析的专家! 💪
现在,是提问环节,大家有什么问题吗? 如果没有,就让我们下次再见! 拜拜! 👋