DataFrames 上的布尔索引
对列应用布尔条件筛选行,并使用 & 和 | 运算符组合多个条件。
DataFrames 上的布尔索引 是 CoddyKit 上的免费 Pandas & NumPy Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Pandas & NumPy Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Pandas & NumPy Academy 课程共包含 4 节课。
什么是布尔索引?
布尔索引通过应用一个会生成由 True 和 False 值组成的 Series 的条件,让您能够筛选 DataFrame 中的行。只有条件为 True 的行才会被返回。这是 Pandas 中最常用的选择技术之一,因为它既易读又快速。
例如,给定一个销售 DataFrame,您可以立即获取所有收入超过 1000 的行,而无需编写循环。
import pandas as pd
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'revenue': [500, 1500, 800, 2000]
})
# Boolean condition produces a Series of True/False
mask = df['revenue'] > 1000
print(mask)
# 0 False
# 1 True
# 2 False
# 3 True应用布尔掩码
获得布尔掩码后,将它放在 DataFrame 的方括号内,即可只选择匹配的行。结果是一个新的 DataFrame——原始 DataFrame 永远不会被修改。原始行的索引会被保留,因此您始终知道每一行的来源。
这种“创建掩码,然后应用掩码”的模式是 Pandas 筛选行的标准写法。
import pandas as pd
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'revenue': [500, 1500, 800, 2000]
})
mask = df['revenue'] > 1000
filtered = df[mask]
print(filtered)
# product revenue
# 1 B 1500
# 3 D 2000不使用掩码变量直接写条件
您不必将布尔 Series 赋给变量。可以将条件直接内联写在方括号中:df[df['col'] > value]。这种单行写法在数据分析笔记本中非常常见,因为它能让代码简洁易读。
两种方式——使用掩码变量和直接内联——会产生完全相同的结果。条件复杂或需要重复使用时,请使用变量;简单的一次性筛选则可以直接内联。
import pandas as pd
df = pd.DataFrame({
'city': ['NYC', 'LA', 'Chicago', 'Houston'],
'population': [8_336_817, 3_979_576, 2_693_976, 2_320_268]
})
# Inline boolean filter
large_cities = df[df['population'] > 3_000_000]
print(large_cities)
# city population
# 0 NYC 8336817
# 1 LA 3979576使用 &(AND)组合条件
如果要求两个条件都为真,请使用 & 运算符将它们组合起来,而不要使用 Python 的 and 关键字,因为后者无法对数组逐元素运算。每个条件都必须用圆括号括起来,因为 & 的运算符优先级高于比较运算符。
结果只会保留所有子条件计算结果都为 True 的行。
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Carol', 'Dave'],
'age': [25, 35, 28, 45],
'salary': [50000, 90000, 70000, 120000]
})
# Both conditions must be true
result = df[(df['age'] > 27) & (df['salary'] > 60000)]
print(result)
# name age salary
# 1 Bob 35 90000
# 2 Carol 28 70000使用 |(OR)组合条件
使用 | 运算符保留至少一个条件为真的行。与 & 一样,每个子条件都必须放在圆括号中。| 运算符会对布尔数组逐元素执行逻辑 OR 运算。
混合使用 & 和 | 完全没问题——只需注意使用圆括号来确保正确的计算顺序,避免出现隐蔽的逻辑错误。
import pandas as pd
df = pd.DataFrame({
'product': ['Laptop', 'Mouse', 'Monitor', 'Keyboard'],
'price': [1200, 25, 300, 80],
'category': ['Electronics', 'Accessories', 'Electronics', 'Accessories']
})
# Rows where price > 200 OR category is Accessories
result = df[(df['price'] > 200) | (df['category'] == 'Accessories')]
print(result)
# product price category
# 0 Laptop 1200 Electronics
# 1 Mouse 25 Accessories
# 2 Monitor 300 Electronics
# 3 Keyboard 80 Accessories使用 ~ 否定条件
波浪号 ~ 运算符会反转布尔 Series——将 True 变为 False,反之亦然。使用 ~ 可以表达“NOT”逻辑:保留不匹配某个条件的行。这比手动构造相反条件更简洁。
例如,df[~df['status'].isin(['cancelled', 'refunded'])] 会保留除这两种状态以外的所有行。
import pandas as pd
df = pd.DataFrame({
'order_id': [1, 2, 3, 4],
'status': ['shipped', 'cancelled', 'delivered', 'refunded']
})
# Keep only rows that are NOT cancelled
active = df[~(df['status'] == 'cancelled')]
print(active)
# order_id status
# 0 1 shipped
# 2 3 delivered
# 3 4 refunded筛选字符串值
布尔索引同样适用于文本列。您可以使用 == 筛选完全匹配的值,也可以在条件中使用 .str 方法(例如 .str.startswith()、.str.contains() 或 .str.upper())进行灵活的文本筛选。
Pandas 中的字符串比较默认区分大小写,因此 'NYC' 和 'nyc' 会被视为不同的值。如有需要,请先统一大小写。
import pandas as pd
df = pd.DataFrame({
'country': ['USA', 'Germany', 'UK', 'USA', 'France'],
'sales': [400, 200, 150, 600, 300]
})
# Filter rows where country equals USA
us_sales = df[df['country'] == 'USA']
print(us_sales)
# country sales
# 0 USA 400
# 3 USA 600
# Filter rows where country starts with 'G'
g_countries = df[df['country'].str.startswith('G')]
print(g_countries)
# country sales
# 1 Germany 200筛选多个列
复杂分析通常需要使用 & 和 | 组合多个列中的条件。为了提高可读性,请将很长的条件拆分为命名的布尔 Series——每个 Series 都作为一个命名的子筛选条件,最后再将它们组合起来。
这种方式可以明确表达您的意图:每一行读起来都像一个英语句子,描述筛选逻辑的一部分。
import pandas as pd
df = pd.DataFrame({
'region': ['North', 'South', 'North', 'East'],
'year': [2022, 2023, 2023, 2022],
'profit': [5000, -200, 8000, 3000]
})
is_north = df['region'] == 'North'
is_2023 = df['year'] == 2023
is_profitable = df['profit'] > 0
result = df[is_north & is_2023 & is_profitable]
print(result)
# region year profit
# 2 North 2023 8000使用 np.where 创建条件列
布尔索引用于筛选行,但有时您希望根据条件添加新列,而不是删除行。np.where(condition, value_if_true, value_if_false) 是逐元素应用于列的 if/else 的向量化等价形式,速度远快于使用 lambda 的 apply。
import pandas as pd
import numpy as np
df = pd.DataFrame({
'score': [45, 72, 88, 61, 95]
})
# Create a new column based on a condition
df['grade'] = np.where(df['score'] >= 70, 'Pass', 'Fail')
print(df)
# score grade
# 0 45 Fail
# 1 72 Pass
# 2 88 Pass
# 3 61 Fail
# 4 95 Pass为筛选出的子集赋值
您可以使用 .loc[mask, column] 就地更新筛选行中的值。这是为子集设置值的安全方式——使用 df[mask]['col'] = value 这样的链式索引可能会引发 SettingWithCopyWarning,因为它操作的是副本。
当您想要就地修改原始 DataFrame 时,请始终优先使用 df.loc[mask, 'col'] = value。
import pandas as pd
df = pd.DataFrame({
'item': ['A', 'B', 'C', 'D'],
'stock': [0, 5, 0, 12]
})
# Mark out-of-stock items
df.loc[df['stock'] == 0, 'status'] = 'Out of Stock'
df.loc[df['stock'] > 0, 'status'] = 'Available'
print(df)
# item stock status
# 0 A 0 Out of Stock
# 1 B 5 Available
# 2 C 0 Out of Stock
# 3 D 12 Available统计并求和掩码
由于布尔值在底层表示为 1(True)和 0(False),您可以对掩码调用 .sum() 来统计匹配的行数,或调用 .mean() 获取匹配行所占的比例。在应用筛选选择行之前,这些快速统计可以帮助您验证筛选逻辑。
import pandas as pd
df = pd.DataFrame({'value': [10, 55, 30, 80, 20, 70]})
mask = df['value'] > 40
print('Count of rows > 40:', mask.sum()) # 3
print('Fraction > 40:', mask.mean().round(2)) # 0.5
# Now apply
print(df[mask])
# value
# 1 55
# 3 80
# 5 70快速检查
测试您对 DataFrame 布尔索引的理解。
课程回顾
在本课中,您学到了:布尔掩码通过对列应用条件来筛选行;& 和 | 运算符可以组合多个条件(而不是 Python 的 and/or);以及 ~ 会反转布尔掩码以实现 NOT 逻辑。使用 df.loc[mask, col] = value 可以安全地为筛选出的行赋值。接下来,我们将探索 query() 方法,以可读字符串的形式编写筛选条件。
用 AI 导师学习 Python — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 30
- 课程
- 120
常见问题解答
「DataFrames 上的布尔索引」课时是免费的吗?
是的 — 「DataFrames 上的布尔索引」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Pandas & NumPy Academy 课程的其余内容,请升级到 CoddyKit PRO。 Pandas & NumPy Academy 课程共包含 4 节课。
「DataFrames 上的布尔索引」这节课中我会学到什么?
对列应用布尔条件筛选行,并使用 & 和 | 运算符组合多个条件。 你通过在浏览器中直接运行的动手代码来练习 Pandas & NumPy Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Pandas & NumPy Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Pandas & NumPy Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「DataFrames 上的布尔索引」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Pandas & NumPy Academy 课中编写并运行代码吗?
能。每节 Pandas & NumPy Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- DataFrames 上的布尔索引
- query() 方法
- isin() 与 between() 筛选
- 按模式选择列