4.4 条件选择 (布尔索引) Pandas 条件选择(布尔索引)详解 在 Pandas 中,条件选择(也称为布尔索引)是一种强大的数据筛选技术,它允许你根据特定条件从 DataFrame 或 Series 中选择数据。这种方法基于布尔数组,该数组的每个元素对应于 DataFrame 或 Series 中的一行(或一个元素), 表示选择该行, 表示排除该行。 4.4.1 基本原理 布尔索引的核心在于创建一个与你的 DataFrame 或 Series 具有相同索引的布尔数组。这个布尔数组通常是通过对 DataFrame 或 Series 应用条件表达式来生成的。 示例: 假设我们有一个 DataFrame ,其中包含有关学生的信息,包括姓名、年龄和成绩。
在 Pandas 中,条件选择(也称为布尔索引)是一种强大的数据筛选技术,它允许你根据特定条件从 DataFrame 或 Series 中选择数据。这种方法基于布尔数组,该数组的每个元素对应于 DataFrame 或 Series 中的一行(或一个元素),True 表示选择该行,False 表示排除该行。
布尔索引的核心在于创建一个与你的 DataFrame 或 Series 具有相同索引的布尔数组。这个布尔数组通常是通过对 DataFrame 或 Series 应用条件表达式来生成的。
示例:
假设我们有一个 DataFrame df,其中包含有关学生的信息,包括姓名、年龄和成绩。
import pandas as pd data = {'姓名': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'], '年龄': [20, 22, 21, 23, 20], '成绩': [85, 92, 78, 88, 95]} df = pd.DataFrame(data) print(df)
输出:
姓名 年龄 成绩 0 Alice 20 85 1 Bob 22 92 2 Charlie 21 78 3 David 23 88 4 Eve 20 95
现在,如果我们想选择所有年龄大于 21 岁的学生,我们可以创建一个布尔数组:
age_filter = df['年龄'] > 21 print(age_filter)
输出:
0 False 1 True 2 False 3 True 4 False Name: 年龄, dtype: bool
age_filter 是一个 Series,其中 True 对应于年龄大于 21 岁的学生,False 对应于年龄小于等于 21 岁的学生。
有了布尔数组,我们就可以使用它来选择 DataFrame 中的行:
selected_students = df[age_filter] print(selected_students)
输出:
姓名 年龄 成绩 1 Bob 22 92 3 David 23 88
selected_students DataFrame 仅包含年龄大于 21 岁的学生的信息。
流程图:
可以使用逻辑运算符(& 表示 "与",| 表示 "或",~ 表示 "非")组合多个条件。
示例:
选择年龄大于 21 岁且成绩大于 90 分的学生:
combined_filter = (df['年龄'] > 21) & (df['成绩'] > 90) selected_students = df[combined_filter] print(selected_students)
输出:
姓名 年龄 成绩 1 Bob 22 92
注意:在使用逻辑运算符组合条件时,需要用括号将每个条件括起来,以确保正确的运算顺序。
.loc 进行条件选择.loc 属性可以与布尔索引结合使用,以实现更精确的选择。.loc 允许你同时指定行和列的选择条件。
示例:
选择年龄大于 21 岁学生的姓名和成绩:
selected_data = df.loc[df['年龄'] > 21, ['姓名', '成绩']] print(selected_data)
输出:
姓名 成绩 1 Bob 92 3 David 88
.loc 的第一个参数是行选择条件(布尔数组),第二个参数是列选择列表。
.isin() 进行选择.isin() 方法用于检查 DataFrame 或 Series 中的值是否包含在给定的列表中。
示例:
选择姓名为 "Alice" 或 "Eve" 的学生:
name_filter = df['姓名'].isin(['Alice', 'Eve']) selected_students = df[name_filter] print(selected_students)
输出:
姓名 年龄 成绩 0 Alice 20 85 4 Eve 20 95
.query() 方法Pandas 提供了 .query() 方法,允许你使用字符串形式的条件表达式进行选择。
示例:
选择年龄大于 21 岁且成绩大于 90 分的学生:
selected_students = df.query('年龄 > 21 and 成绩 > 90') print(selected_students)
输出:
姓名 年龄 成绩 1 Bob 22 92
.query() 方法的优点是语法简洁,易于阅读。
在进行条件选择时,需要注意空值(NaN)的处理。包含空值的条件表达式可能返回 NaN,导致选择结果不准确。
示例:
假设 DataFrame 中包含空值:
import numpy as np data = {'姓名': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'], '年龄': [20, 22, 21, 23, np.nan], '成绩': [85, 92, 78, 88, 95]} df = pd.DataFrame(data) print(df)
输出:
姓名 年龄 成绩 0 Alice 20.0 85 1 Bob 22.0 92 2 Charlie 21.0 78 3 David 23.0 88 4 Eve NaN 95
如果直接使用 df['年龄'] > 21 作为条件,包含空值的行将返回 NaN。
为了避免这个问题,可以使用 .notna() 或 .fillna() 方法处理空值。
示例:
# 移除包含空值的行 df_no_na = df.dropna(subset=['年龄']) selected_students = df_no_na[df_no_na['年龄'] > 21] print(selected_students) # 或者,填充空值 df_filled = df['年龄'].fillna(df['年龄'].mean()) # 用平均值填充 selected_students = df[df_filled > 21] print(selected_students)
对于大型 DataFrame,布尔索引的性能可能成为一个问题。以下是一些提高性能的建议:
避免链式索引: 链式索引(例如 df[df['A'] > 0]['B'])可能会导致性能下降。建议使用 .loc 进行选择,例如 df.loc[df['A'] > 0, 'B']。
使用 NumPy 优化: 如果性能至关重要,可以考虑将 Pandas Series 转换为 NumPy 数组,然后进行条件选择。
使用 Categorical 类型: 如果 DataFrame 中包含重复的字符串值,可以将其转换为 Categorical 类型,以减少内存占用并提高性能。
条件选择(布尔索引)是 Pandas 中一种强大的数据筛选技术。通过创建布尔数组并将其应用于 DataFrame 或 Series,可以轻松地选择满足特定条件的数据。掌握条件选择技巧可以帮助你更有效地分析和处理数据。
希望本文能够帮助你理解 Pandas 中的条件选择(布尔索引)。