4.5 复杂索引与切片 4.5 复杂索引与切片 4.5.1 多轴索引 Pandas 的 DataFrame 是一个二维表格数据结构,因此选择数据通常涉及指定行和列。 使用 和 索引器,我们可以同时指定行和列的标签或位置。 :基于标签的索引 允许我们使用行和列的标签进行选择。 输出: 输出: :基于位置的索引 允许我们使用行和列的整数位置进行选择。 输出: 4.5.2 布尔索引 布尔索引允许我们基于条件表达式选择行。 这是一种强大的过滤数据的方法。 输出: 多条件组合 可以使用 (与), (或), 和 (非) 运算符组合多个条件。 请务必使用括号来明确运算的优先级。 输出: 4.5.3 使用 方法 方法提供了一种更简洁的方式来使用字符串表达式进行数据过滤。 输出与前面的布尔索引示例相同。 4.
Pandas 的 DataFrame 是一个二维表格数据结构,因此选择数据通常涉及指定行和列。 使用 .loc 和 .iloc 索引器,我们可以同时指定行和列的标签或位置。
.loc:基于标签的索引
.loc 允许我们使用行和列的标签进行选择。
import pandas as pd # 创建示例 DataFrame data = {'姓名': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'], '年龄': [25, 30, 22, 28, 24], '城市': ['北京', '上海', '广州', '深圳', '杭州'], '分数': [85, 92, 78, 88, 95]} df = pd.DataFrame(data) df = df.set_index('姓名') # 将姓名设置为索引 print(df)
输出:
年龄 城市 分数 姓名 Alice 25 北京 85 Bob 30 上海 92 Charlie 22 广州 78 David 28 深圳 88 Eve 24 杭州 95
# 选择 'Alice' 行的 '年龄' 和 '城市' 列 result = df.loc['Alice', ['年龄', '城市']] print(result) # 选择 'Alice' 到 'Charlie' 行的 '年龄' 到 '分数' 列 result = df.loc['Alice':'Charlie', '年龄':'分数'] print(result)
输出:
年龄 25 城市 北京 Name: Alice, dtype: object 年龄 城市 分数 姓名 Alice 25 北京 85 Bob 30 上海 92 Charlie 22 广州 78
.iloc:基于位置的索引
.iloc 允许我们使用行和列的整数位置进行选择。
# 选择第一行(索引 0)的所有列 result = df.iloc[0, :] # 或者 df.iloc[0] print(result) # 选择前两行和前两列 result = df.iloc[:2, :2] print(result)
输出:
年龄 25 城市 北京 分数 85 Name: Alice, dtype: object 年龄 城市 姓名 Alice 25 北京 Bob 30 上海
布尔索引允许我们基于条件表达式选择行。 这是一种强大的过滤数据的方法。
# 选择年龄大于 25 的行 result = df[df['年龄'] > 25] print(result) # 选择城市为 '北京' 或 '上海' 的行 result = df[df['城市'].isin(['北京', '上海'])] print(result) # 选择分数在 80 到 90 之间的行 result = df[(df['分数'] >= 80) & (df['分数'] <= 90)] print(result)
输出:
年龄 城市 分数 姓名 Bob 30 上海 92 David 28 深圳 88 年龄 城市 分数 姓名 Alice 25 北京 85 Bob 30 上海 92 年龄 城市 分数 姓名 Alice 25 北京 85 David 28 深圳 88
多条件组合
可以使用 & (与), | (或), 和 ~ (非) 运算符组合多个条件。 请务必使用括号来明确运算的优先级。
# 选择年龄大于 25 且分数大于 85 的行 result = df[(df['年龄'] > 25) & (df['分数'] > 85)] print(result)
输出:
年龄 城市 分数 姓名 Bob 30 上海 92 David 28 深圳 88
query() 方法query() 方法提供了一种更简洁的方式来使用字符串表达式进行数据过滤。
# 使用 query() 选择年龄大于 25 的行 result = df.query('年龄 > 25') print(result) # 使用 query() 选择城市为 '北京' 或 '上海' 的行 result = df.query('城市 in ["北京", "上海"]') print(result) # 使用 query() 选择年龄大于 25 且分数大于 85 的行 result = df.query('年龄 > 25 and 分数 > 85') print(result)
输出与前面的布尔索引示例相同。
isin() 方法isin() 方法用于检查 DataFrame 的列中的值是否包含在指定列表中。
# 选择城市为 '北京' 或 '上海' 的行 result = df[df['城市'].isin(['北京', '上海'])] print(result)
输出:
年龄 城市 分数 姓名 Alice 25 北京 85 Bob 30 上海 92
链式索引是指连续使用多个 [] 索引操作。 虽然它在某些情况下可以工作,但通常不推荐使用,因为它可能会导致意外的结果或性能问题。 建议使用 .loc 或 .iloc 进行更明确和可靠的索引。
不推荐的链式索引示例:
# 不推荐:链式索引 # 这种方式可能会导致 SettingWithCopyWarning,并且行为不确定 # df[df['年龄'] > 25]['城市'] # 避免这种写法
推荐的 .loc 索引示例:
# 推荐:使用 .loc 进行索引 result = df.loc[df['年龄'] > 25, '城市'] print(result)
输出:
姓名 Bob 上海 David 深圳 Name: 城市, dtype: object
除了基本的切片操作之外,Pandas 还支持更高级的切片技术。
[start:stop:step] 语法指定切片的步长。# 选择前 4 行,每隔一行选择一次 result = df.iloc[:4:2] print(result)
输出:
年龄 城市 分数 姓名 Alice 25 北京 85 Charlie 22 广州 78
where() 方法where()方法是根据条件替换值的方法。满足条件的保留,不满足条件的替换。
import numpy as np # 将分数小于85的替换为NaN result = df.where(df['分数'] >= 85) print(result) result2 = df.where(df['分数'] >= 85, other=0) # 将不满足条件的值替换为0 print(result2)
输出:
年龄 城市 分数 姓名 Alice 25.0 北京 85.0 Bob 30.0 上海 92.0 Charlie NaN NaN NaN David NaN NaN NaN Eve 24.0 杭州 95.0
年龄 城市 分数 姓名 Alice 25 北京 85 Bob 30 上海 92 Charlie 0 0 0 David 0 0 0 Eve 24 杭州 95
以下是一个 Mermaid 图表,总结了 Pandas 中复杂索引和切片的主要方法:
图表解释:
DataFrame: 表示 Pandas 的 DataFrame 对象。
索引方法: 表示用于选择和过滤数据的各种方法。
.loc (标签索引): 使用行和列的标签进行选择。
.iloc (位置索引): 使用行和列的整数位置进行选择。
布尔索引: 基于条件表达式选择行。
query() 方法: 使用字符串表达式进行数据过滤。
isin() 方法: 检查列中的值是否包含在指定列表中。
单轴选择: 仅选择行或列。
多轴选择: 同时选择行和列。
单条件: 使用单个条件进行过滤。
多条件组合: 使用 &, |, 和 ~ 运算符组合多个条件。
字符串表达式: 使用字符串表达式进行数据过滤
根据条件替换值: 根据条件替换 DataFrame 中的值
复杂索引和切片是 Pandas 中数据选择和过滤的关键技术。 通过掌握 .loc、.iloc、布尔索引、query() 和 isin() 方法,可以灵活地提取所需的数据子集,并进行更深入的数据分析。 始终注意避免链式索引,并使用 .loc 或 .iloc 进行更明确和可靠的索引操作。 熟练掌握这些技术将极大地提高数据处理的效率和准确性。