学径XUEJING · 个人学习平台通知设置

课程库 AI 主线 pandas 数据处理 › 第 4

选取与过滤 —— loc/iloc 与条件筛选

普通课60 分钟

本课导读

"把上海的订单挑出来""看一下金额前三的行""只要产品和金额两列"——数据分析一半的日常就是从大表里取你要的那块。本课学三套选取姿势:方括号选列、loc/iloc 选行、布尔筛选按条件挑行(本课的重头戏,也是 pandas 最有表现力的语法)。学完这课,你对一张表就真正做到指哪打哪。预计 60 分钟。

道具表(本课通用)

Python

(后面每个代码块都会重建这份道具——沙盒约定,任意顺序运行不炸。)

一、选列:方括号两副面孔

Python

规则一句话:方括号里放列名字符串得 Series,放列名列表得 DataFrame。双层方括号看着怪,拆开看就懂——外层是取数动作,内层 ["product", "price"] 是一个普通列表。

二、选行:loc 按标签,iloc 按位置

Python

一对双胞胎,分工记牢:

  • iloc = 按位置(integer):第几行第几列,规则和列表切片完全一致(含头不含尾)
  • loc = 按标签:行标签 + 列名。有个偏门脾气——loc 的切片含两端0:2 是三行),因为标签切片"到 2 为止"比"到 2 之前"更符合直觉
  • 现阶段行标签就是自动编号,两者看着像;将来遇到"日期做行标签"的表,loc 的价值才完全展开。先建立肌肉:位置用 iloc,标签/列名用 loc

三、布尔筛选:本课的主菜

上一课埋的伏笔收网。"整列比较"得到一列 True/False,把它塞回方括号——True 的行留下

Python

读法口诀:df[df["total"] > 500] 读作"df 里 total 大于 500 的那些行"——里层造筛子,外层过筛子。

组合条件,两个新符号两个坑:

Python

说明

布尔筛选两大坑,新手命中率 90%:① 用了 and/or——整列比较必须用 &|(and/or 是单个值的逻辑词,对整列直接报错);② 忘加括号——& 的优先级高于比较运算,df["a"] > 1 & df["b"] < 2 会先算中间的 &,报一堆看不懂的错。肌肉记忆:每个条件独立包括号

四、排序 + 取头部:TopN 连招

Python

sort_values("列", ascending=False) 降序排(注意:交回新表,原表不动——sorted() 的脾气,不是 .sort() 的)。链式连招 df.sort_values(...).head(3)[["列"]] 一行完成"排序 → 取前三 → 挑列",这种流水线式写法是 pandas 的日常体态。

✍️ 练习

练习 1:三种选取各来一下

从道具表中:① 取 product 单列 ② 取 product 和 city 两列 ③ 用 iloc 取最后两行。

Python
✅ 参考答案
import pandas as pd

raw = """order_id,product,price,qty,city
1001,键盘,299,1,上海
1002,鼠标,89,2,北京
1003,显示器,1599,1,上海
1004,键盘,299,3,深圳"""
with open("orders.csv", "w", encoding="utf-8") as f:
    f.write(raw)
df = pd.read_csv("orders.csv")

print(df["product"])
print(df[["product", "city"]])
print(df.iloc[-2:])

练习 2:筛选实战

行政小美查报销:筛出 ① 金额超 200 的餐费 ② 部门是"设计"或"运营"的全部报销(用 isin)。

Python
💡 提示

① 两个条件(type 是餐费 amount > 200)——& 加括号。② df["dept"].isin([...])

✅ 参考答案
import pandas as pd

raw = """name,dept,type,amount
小雨,设计,餐费,180
阿杰,运营,交通,95
丽丽,设计,餐费,260
老王,销售,餐费,320
小陈,运营,办公,150"""
with open("expense.csv", "w", encoding="utf-8") as f:
    f.write(raw)
df = pd.read_csv("expense.csv")

print(df[(df["type"] == "餐费") & (df["amount"] > 200)])
print(df[df["dept"].isin(["设计", "运营"])])

练习 3:连招挑战

一行链式完成:筛出北京和上海的订单 → 按 total 降序 → 取前两名 → 只显示 city、product、total 三列。

Python
✅ 参考答案
import pandas as pd

raw = """order_id,product,price,qty,city
1001,键盘,299,1,上海
1002,鼠标,89,2,北京
1003,显示器,1599,1,上海
1004,键盘,299,3,深圳
1005,鼠标,89,1,北京
1006,耳机,459,2,上海"""
with open("orders.csv", "w", encoding="utf-8") as f:
    f.write(raw)
df = pd.read_csv("orders.csv")
df["total"] = df["price"] * df["qty"]

result = (
    df[df["city"].isin(["北京", "上海"])]
    .sort_values("total", ascending=False)
    .head(2)[["city", "product", "total"]]
)
print(result)

外面包一层圆括号就能把长链断行——可读性和链式两不误(PEP8 行长规矩的 pandas 应用)。

📝 随堂测验

随堂测验0 / 5 题正确

1. df[["a", "b"]] 双层方括号的含义是?

2. iloc 和 loc 的分工是?

3. df[df["total"] > 500] 的工作原理是?

4. df[(df["a"] > 1) & (df["b"] < 5)] 里,为什么不能写 and、为什么要括号?

5. “挑出产品在指定清单里的行”,最优雅的写法是?

本课小结

  • 选列:字符串→Series,列表→DataFrame(双层方括号);选行:位置 iloc(含头不含尾)、标签 loc(含两端)
  • 布尔筛选 = 造筛子(整列比较)+ 过筛子(塞回方括号);组合用 & | 且每个条件包括号,名单用 isin
  • TopN 连招:sort_values(..., ascending=False).head(n)——sort_values 交新表不动原表
  • 链式流水线是 pandas 的日常体态,长链包圆括号断行

下一课直面真实数据的常态——脏:缺失、重复、类型错乱、空格幽灵,一门课学会给数据"洗澡"。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…