布尔索引最高效但必须加括号;query更易读且支持变量引用;复杂逻辑如“至少两列满足”需用.ge().sum(axis=1)向量化计数。

直接用布尔索引最高效,但必须加括号;query写法更易读,适合动态条件;复杂逻辑(如“至少两列满足”)得靠向量化计数。
布尔索引:为什么括号不能省,& 和 | 怎么用
每个独立条件必须用括号包裹,否则 & 会先于 == 执行,直接报 ValueError: The truth value of a Series is ambiguous。这不是风格问题,是语法强制要求。
-
(df["城市"] == "北京") & (df["年龄"] > 30)✅ 正确 -
df["城市"] == "北京" & df["年龄"] > 30❌ 报错 - 多个
&条件可换行写,提升可读性,也方便逐条调试 -
|是“或”,~是“非”,三者优先级相同,全都要括号
query 方法:像 SQL 一样写条件,但要注意变量引用
query 避开了运算符优先级陷阱,天然支持列名直写,不用重复敲 df[...],特别适合从数据库转过来的人。但它不支持所有 Python 表达式,比如不能调用自定义函数。
-
df.query("城市 == '北京' and 年龄 > 30")✅ 简洁直观 -
df.query("年龄 > @min_age and 收入 > @threshold")✅ 用@引用外部变量 - 含空格或特殊字符的列名需用反引号:`df.query("`用户 ID` > 100")`
- 性能上,小数据集差异不大;百万行以上,纯布尔索引通常快 10%–20%
“至少 N 列满足条件”:用 .ge() + .sum(axis=1)
这不是常规的“与/或”逻辑,而是计数型筛选——比如“4 门课中至少 2 门 ≥85”。硬写 | 组合会爆炸(C(4,2)=6 种组合),必须转向量化统计。
df[ df[["数学","英语","物理","化学"]].ge(85).sum(axis=1) >= 2 ]-
.ge(85)返回布尔 DataFrame,sum(axis=1)自动把True/False当 1/0 加总 - 含
NaN时,.ge(85)默认返回False,会少计一票;若需忽略缺失值,先fillna(0)或用dropna() - 列名建议提前存为变量:
score_cols = ["数学","英语","物理","化学"],再套用,避免硬编码
用 mask 做条件替换,不是筛选
mask 的本质是“满足条件就替换”,不是过滤行。它和 where 是一对反操作:一个替 True,一个替 False。新手常误把它当 loc 用。
df["score"].mask(df["score"] → 把不及格分数设为 <code>NaN- 多条件组合同样要括号:
df.mask((df["age"] - 想保留原始结构只改部分值,
mask比loc+ 赋值更安全(不会因索引错位写漏) - 若目标是删行,别用
mask,该用布尔索引或query
最容易被忽略的是空值处理——==、.ge()、str.contains() 遇到 NaN 全返回 False,导致本该匹配的行被漏掉。真要保精度,得先明确策略:填默认值?跳过?还是用 isna() 单独处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











