适用范围: 概念题、代码阅读题、代码补全题、简答题、分析题与综合应用题。
原始资料: 《Python数据分析复习资料_按时间顺序合并.docx》。
编辑处理: 按知识体系重新编排;删除 1 组逐字一致的 pandas 重复章节(204 个重复内容块);保留其余课程知识、代码模板、易错点、自测题和考前速览。
内容来源标记#
本文严格使用两类来源标记:
- 原文件内容:来自用户上传的合并资料。第 1—8 章均属于这一类;其中只做结构重排、标题规范化和重复项合并。
- 外部补充:不属于课程原文件,集中放在文末“附录 A 外部补充”中,并逐条给出参考来源。复习时不要把这部分误认为教师原讲授范围。
推荐复习顺序#
| 阶段 | 建议内容 | 目标 |
|---|---|---|
| 第一轮 | 每章“知识框架”“核心概念速查表” | 建立全局知识地图 |
| 第二轮 | “重点知识详解”“公式与指标” | 理解概念、条件与方法差异 |
| 第三轮 | “Python 实现与代码模板” | 能读、能补、能写常见代码 |
| 第四轮 | “课堂重点与考试提示”“高频易错点” | 修正常见误区 |
| 第五轮 | 折叠的“自测题与参考答案” | 检验输出判断与应用分析能力 |
| 考前 | 每章“一页纸考前速览” | 快速回忆 |
全书目录#
- 第 1 章 课程导论与 Python 语法回顾
- 第 2 章 pandas 数据结构与基础操作
- 第 3 章 数据读写 清洗 聚合与分组
- 第 4 章 数据可视化 Matplotlib
- 第 5 章 探索式数据分析 EDA
- 第 6 章 机器学习基础
- 第 7 章 图像数据分析
- 第 8 章 文本数据分析基础
- 附录 A 外部补充
- 附录 B 参考资料
通用综合题答题框架#
- 明确问题:研究对象、目标变量、分析单位和业务问题是什么。
- 检查数据:形状、字段类型、缺失、重复、异常值及取值范围。
- 选择方法:根据变量类型、样本关系和任务目标选择统计量、图表或模型。
- 实施分析:给出关键参数和代码,说明输入、输出及数据结构。
- 解释结果:把数值、图形或评价指标翻译为可理解的结论。
- 说明局限:样本偏差、相关不等于因果、模型假设、数据泄漏或泛化风险。
第 1 章 课程导论与 Python 语法回顾#
内容来源:原文件内容。 课程介绍 PPT《0-课程介绍-20260301.pdf》与 2026-03-02 课堂转录。
1. 本讲/本章知识框架#
1.1 课程定位与学习目标#
- 课程性质:大数据管理与应用专业必修;图书馆学、信息管理与信息系统为专业选修;其他与“数据”“智能”相关方向也可选修。
- 课程核心:Python 是实践工具,数据分析是学习目标。老师反复强调“本课程不是语法课”。
- 能力目标:能读写较复杂 Python 程序;掌握 NumPy、pandas、matplotlib、seaborn;能用 Python 解决实际数据分析问题。
1.2 课程内容结构#
| 篇章 | 主要内容 | 学习重点 |
|---|---|---|
| 基础篇 | Python 语法回顾;NumPy;pandas;数据读写;数据清洗;聚合与分组;matplotlib 与 seaborn。 | 掌握数据分析所需的基本工具与表格数据操作。 |
| 应用篇 | 探索式数据分析、时序数据分析、机器学习、社会网络分析、图像分析、文本挖掘。 | 把工具用于真实数据场景,形成“问题—方法—解释”的分析闭环。 |
1.3 本讲知识主线#
| 模块 | 核心问题 | 要点 |
|---|---|---|
| 数据分析导论 | 什么是数据分析?为什么不是单纯写代码? | 从数据中发现规律、建立模型、辅助解释和决策。 |
| 典型案例 | 数据分析能做什么? | 啤酒与尿布、流感预测、用户画像、知识图谱、银行流失预警、聊天记录分析等。 |
| Python 语法回顾 | 后续分析所需的基础语法有哪些? | 条件、循环、切片、四类数据结构、推导式、生成器、拷贝、函数、lambda、模块化。 |
| 工具包概览 | 哪些包对应哪些分析任务? | NumPy 数组;pandas 表格;matplotlib/seaborn 可视化;statsmodels/SciPy/sklearn 建模。 |
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| 数据分析 | Data Analysis | 从数据中提取信息、发现规律、建立模型并支持解释或决策。 | 各类结构化、文本、图像、网络数据。 | 不是单纯写代码或画图。 | 为什么本课程重点不是 Python 语法? |
| 探索式数据分析 | EDA | 建模前用统计量和图表理解数据结构、分布、异常与关系。 | 拿到一份新数据后的第一阶段。 | EDA 不是最终建模,而是先理解数据。 | 拿到新数据后应如何开始分析? |
| 关联规则挖掘 | Association Rule Mining | 发现交易数据中物品共现规律。 | 购物篮分析,如啤酒与尿布。 | 共现不等于因果。 | 啤酒与尿布案例说明什么? |
| 回归 | Regression | 用已有样本拟合变量关系,并预测连续型结果。 | 流感趋势、经济指标、销售额预测。 | 回归预测连续值,分类预测类别。 | 用通俗语言解释回归模型。 |
| 用户画像 | User Profiling | 用行为数据构造特征,刻画用户模式。 | 电信、推荐、广告、风控。 | 不是识别真实身份,而是行为模式刻画。 | 如何用移动数据构建用户画像? |
| 聚类 | Clustering | 在无标签条件下将相似对象分组。 | 用户分群、地点识别、行为模式发现。 | 聚类无标签;分类有标签。 | 为什么用户画像可以使用聚类? |
| 文本向量化 | Text Vectorization | 将文本转化为数值向量。 | 文本相似度、主题识别、文本分类。 | 不能直接比较原始文字。 | 如何比较两句话是否相似? |
| 余弦相似度 | Cosine Similarity | 用两个向量夹角衡量方向相似。 | 文本相似、推荐系统。 | 关注方向,不直接关注长度。 | 余弦相似度适合什么场景? |
| 欧氏距离 | Euclidean Distance | 多维空间中两点间直线距离。 | 聚类、相似度计算。 | 受量纲和尺度影响,需要标准化。 | 欧氏距离和余弦相似度有何区别? |
| 网络数据 | Network Data | 用节点表示实体、用边表示关系。 | 社会网络、引文网络、知识图谱。 | 重点是关系,不只是属性。 | 什么情况下应将数据表示为网络? |
| 列表 | list | 可变、有序、可重复的序列。 | 存放可修改的一组元素。 | 与 tuple 的可变性不同。 | list 与 tuple 的区别? |
| 元组 | tuple | 不可变、有序、可重复的序列。 | 常量、字典键、保护数据。 | 不能 append/remove。 | tuple 为什么可作为字典 key? |
| 字典 | dict | 键值对结构,key 唯一。 | 映射查询,如姓名—工资。 | key 不能重复,通常要求不可变。 | dict 的 key 有什么要求? |
| 集合 | set | 无序、元素不重复的集合结构。 | 去重、集合运算。 | 不能用下标访问。 | set 和 list 的区别? |
| 列表推导式 | List Comprehension | 用一行表达式生成列表。 | 简化循环生成列表。 | 过度嵌套会降低可读性。 | 把 for 循环改写为列表推导式。 |
| 生成器表达式 | Generator Expression | 惰性生成元素的表达式。 | 大数据、节省内存。 | 不是 tuple,通常只能遍历一次。 | 为什么生成器更省内存? |
| 浅拷贝 | Shallow Copy | 复制外层对象,内部子对象仍共享。 | 一层结构或只需外层独立。 | 嵌套结构会共享内层对象。 | 浅拷贝和深拷贝区别? |
| 深拷贝 | Deep Copy | 递归复制对象及其子对象。 | 嵌套结构需要完全独立。 | 成本更高。 | 何时必须使用 deepcopy? |
| NumPy | Numerical Python | 科学计算库,核心对象为 ndarray。 | 向量、矩阵、数值计算、图像像素。 | 不同于 list,强调数组化计算。 | NumPy 的核心对象是什么? |
| pandas | pandas | 表格数据分析库,核心为 Series 和 DataFrame。 | 二维表格、Excel/CSV 数据。 | DataFrame 不等于普通二维 list。 | Series 和 DataFrame 的区别? |
| matplotlib | Matplotlib | Python 基础绘图库。 | 需要高度定制的图表。 | 代码较繁琐但灵活。 | 什么时候用 matplotlib? |
| seaborn | Seaborn | 基于 matplotlib 的统计可视化库。 | 快速绘制统计图。 | 细节定制不如 matplotlib。 | seaborn 的优缺点? |
| scikit-learn | scikit-learn | 机器学习工具包。 | 分类、回归、聚类、降维、预处理。 | 不是深度学习框架。 | sklearn 常用于哪些任务? |
3. 重点知识详解#
3.1 本课程不是语法课#
| 项目 | 内容 |
|---|---|
| 概念定义 | 本课程用 Python 实现数据分析,但核心是数据分析理论、方法和实践。 |
| 直观理解 | 会背函数名不等于会分析数据;真正重要的是拿到数据后知道问什么、用什么方法、如何解释。 |
| PPT 对应内容 | PPT 明确写出“本课程不是语法课!课程重点:数据分析的理论和实践;使用工具:Python”。 |
| 老师课堂强调 | 不要死记所有函数。工具包函数可以查,重点是理解分析任务和方法选择。 |
| 典型例子 | pandas、matplotlib、seaborn 是工具;同一问题也可用其他工具实现。 |
| 可能考点 | 解释“为什么本课程不是 Python 语法课”。 |
| 常见错误 | 把复习重点放在背 API,忽略分析思路、图表选择和结果解释。 |
| 标准答题表述 | 本课程以 Python 为实践工具,核心目标是掌握数据分析理论、方法和应用能力。Python 语法和工具包是实现分析的手段,不能替代对数据问题、方法选择和结果解释的理解。 |
3.2 数据分析的基本思想#
| 项目 | 内容 |
|---|---|
| 概念定义 | 从原始数据中提取信息、发现规律、建立模型,并服务于解释、预测或决策。 |
| 直观理解 | 数据只是记录,分析要回答“发生了什么、为什么发生、将来怎样、应如何行动”。 |
| PPT 对应内容 | 应用篇包括 EDA、时序、机器学习、网络、图像、文本等多个场景。 |
| 老师课堂强调 | 数据分析常常没有简单的绝对对错,更多看分析是否合理、是否满足需求。 |
| 典型例子 | 银行客户流失预警:历史客户行为特征 → 预测谁可能流失 → 提前干预。 |
| 可能考点 | 数据分析与编程、统计、可视化之间的关系。 |
| 常见错误 | 只输出图表或模型结果,不解释业务含义;把相关性当因果性。 |
3.3 啤酒与尿布:关联规则挖掘#
| 项目 | 内容 |
|---|---|
| 概念定义 | 关联规则挖掘用于发现交易数据中不同物品之间的共现关系。 |
| 直观理解 | 商品表面无关,但可能经常被同一批顾客一起购买。 |
| PPT/课堂对应内容 | 老师用“啤酒与尿布”作为经典数据挖掘案例。 |
| 老师课堂强调 | 背后的数据是购物篮数据;转录中的“IP growth”应为 FP-growth。 |
| 典型例子 | 购买尿布的人也常买啤酒,可用于货架布局或促销组合。 |
| 可能考点 | 关联规则挖掘适合什么数据类型? |
| 常见错误 | 把共现关系直接解释成因果关系。 |
3.4 Google 流感预测:行为数据 + 回归模型#
| 项目 | 内容 |
|---|---|
| 概念定义 | 回归通过已有样本拟合变量关系,并预测新样本的连续型结果。 |
| 直观理解 | 过去的数据点形成趋势线,新点来了后根据其特征预测结果。 |
| 课堂对应内容 | Google 将搜索词行为数据与 CDC 流感数据结合,预测流感传播趋势。 |
| 老师课堂强调 | Google 的优势不是医疗知识,而是搜索行为数据;发烧、咳嗽等搜索词可反映趋势。 |
| 典型例子 | 搜索相关症状词频率上升,可能对应流感传播增强。 |
| 可能考点 | 用通俗语言解释回归;说明搜索数据为什么能用于流感预测。 |
| 常见错误 | 忽视搜索行为变化、模型漂移等局限,把预测视为绝对事实。 |
3.5 用户画像:行为特征向量化#
| 项目 | 内容 |
|---|---|
| 概念定义 | 用位置、通话、App 使用等数据构造特征,刻画用户行为模式。 |
| 直观理解 | 不一定知道用户是谁,但可以知道用户“像什么样的人”。 |
| 课堂对应内容 | 移动电信数据案例:基站日志、位置变化、通话行为、App 使用。 |
| 老师课堂强调 | 画像不是画脸,而是用数据勾勒行为习惯。每个用户可表示为特征向量。 |
| 典型例子 | 工作日白天在城区、晚上回郊区,可推断通勤模式;移动速度可辅助判断交通方式。 |
| 可能考点 | 用户画像常见特征;为什么可以用聚类做用户分群? |
| 常见错误 | 把画像理解成真实身份识别;忽视隐私和伦理问题。 |
3.6 文本分析:把文本变成向量#
| 项目 | 内容 |
|---|---|
| 概念定义 | 对文本进行分词、去停用词、词形归一后,将文本转化为向量。 |
| 直观理解 | 机器不能直接理解句子,要先把句子转化为数字。 |
| 课堂对应内容 | 老师用两个句子 X、Y 的词汇出现情况举例,出现记 1,未出现记 0。 |
| 老师课堂强调 | 词形变化需要统一,例如 analysis 的不同形式要归到同一词根或词形。 |
| 典型例子 | 两句话含有大量相同实词,则向量相似度较高。 |
| 可能考点 | 如何比较两个文本是否相似? |
| 常见错误 | 直接比较字符串表面形式;忽视停用词、词形变化和语义差异。 |
3.7 网络数据与知识图谱#
| 项目 | 内容 |
|---|---|
| 概念定义 | 网络数据用节点表示实体,用边表示实体之间的关系。 |
| 直观理解 | 表格关注“对象有什么属性”,网络关注“对象之间有什么关系”。 |
| 课堂对应内容 | 科学知识图谱、论文作者、引文、共词、共引等关系。 |
| 老师课堂强调 | 关系本身也是一种数据,可分析核心人物、边缘人物、知识扩散和知识融合。 |
| 典型例子 | 作者合作网络、论文引文网络、关键词共现网络。 |
| 可能考点 | 什么情况下应使用网络分析? |
| 常见错误 | 只统计节点属性,不分析边和网络结构。 |
3.8 Python 基础数据结构#
| 项目 | 内容 |
|---|---|
| 概念定义 | list、tuple、dict、set 是 Python 中最常用的内置数据结构。 |
| 直观理解 | list 管可变序列;tuple 管不可变序列;dict 管键值映射;set 管去重和集合运算。 |
| 老师课堂强调 | list 和 tuple 的核心区别是可变性;tuple 因不可变更安全,也可作为 dict 的 key。 |
| 可能考点 | 四类结构的特点、可变性、是否有序、是否允许重复。 |
| 常见错误 | 对 set 使用下标访问;修改 tuple;dict key 重复或使用可变对象作 key。 |
3.9 列表推导式与生成器表达式#
| 项目 | 内容 |
|---|---|
| 概念定义 | 列表推导式一次性生成 list;生成器表达式惰性生成元素。 |
| 直观理解 | 列表像一次性把饭全部盛好;生成器像需要时一口一口取。 |
| 老师课堂强调 | 生成器表达式不是 tuple,访问一次后通常就耗尽。 |
| 可能考点 | 判断代码输出;解释为什么生成器节省内存。 |
| 常见错误 | 把圆括号生成器误认为 tuple;第二次遍历期望还有数据。 |
3.10 赋值、浅拷贝、深拷贝#
| 项目 | 内容 |
|---|---|
| 概念定义 | 赋值不复制对象;浅拷贝复制外层对象;深拷贝递归复制所有层级对象。 |
| 直观理解 | 赋值是同一个对象多个名字;浅拷贝只复印封面;深拷贝连里面内容全部复印。 |
| 老师课堂强调 | 嵌套结构中最容易考、也最容易错。 |
| 可能考点 | 给出嵌套 list 代码,判断各变量最终输出。 |
| 常见错误 | 以为 b = a 是复制;以为浅拷贝能避免所有联动。 |
4. Python 实现与代码模板#
本节代码包含两类:一类是课堂语法回顾中明确涉及的基础模板;另一类标注为“根据课程内容整理的通用模板”,用于把课堂案例转化为可操作代码。
4.1 常用导入模板#
# 根据课程内容整理的通用模板import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns
from sklearn.model_selection import train_test_splitfrom sklearn.cluster import KMeansfrom sklearn.metrics.pairwise import cosine_similarityimport copy用途:NumPy 做数组计算;pandas 做表格数据;matplotlib/seaborn 画图;sklearn 做机器学习;copy 做拷贝。易错点:缺包会报 ModuleNotFoundError。
4.2 条件判断模板#
score = 85
if score >= 90: level = "A"elif score >= 80: level = "B"elif score >= 60: level = "C"else: level = "D"
print(level)用途:多条件判断。易错点:条件后必须有冒号;缩进必须一致。
4.3 循环、break、continue、pass#
for i in range(5): print(i) # 0, 1, 2, 3, 4
for i in range(5): if i == 3: break print(i) # 0, 1, 2
for i in range(5): if i == 3: continue print(i) # 0, 1, 2, 4
for letter in "Python": if letter == "h": pass print(letter)break 结束整个循环;continue 跳过本轮;pass 只占位。
4.4 字符串与列表切片#
name = "ABCDEF"print(name[0]) # Aprint(name[0:3]) # ABC,左闭右开print(name[1:-1]) # BCDEprint(name[::-1]) # FEDCBAprint(name[::2]) # ACE
nums = [10, 20, 30, 40, 50]print(nums[1:4]) # [20, 30, 40]标准记忆:seq[start:end
4.5 list、tuple、dict、set#
numbers = [1, 2, 3]numbers.append(4)numbers.insert(1, 100)numbers.remove(2)
point = (10, 20)# point[0] = 99 # TypeError
student = {"name": "Alice", "score": 95}student["score"] = 98student["grade"] = "A"
items = [1, 2, 2, 3, 3]unique_items = set(items)list 可变;tuple 不可变;dict 是键值映射;set 去重。
4.6 列表推导式#
squares = [x ** 2 for x in range(10)]even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
nested = [[1, 2], [3, 4], [5, 6]]flat = [num for sublist in nested for num in sublist]print(flat) # [1, 2, 3, 4, 5, 6]用途:简化“循环 + append”。易错点:嵌套推导式顺序与普通嵌套循环一致。
4.7 生成器表达式#
g = (x ** 2 for x in range(5))print(next(g)) # 0print(next(g)) # 1
for value in g: print(value) # 4, 9, 16
for value in g: print(value) # 没有输出,因为生成器已耗尽用途:大数据中节省内存。易错点:生成器不是 tuple,通常只能遍历一次。
4.8 赋值、浅拷贝、深拷贝#
import copy
a = [[1, 2], [3, 4]]b = a # 赋值:共享同一对象c = copy.copy(a) # 浅拷贝:外层不同,内层共享d = copy.deepcopy(a) # 深拷贝:完全独立
a[0].append(99)a.append([5, 6])
print("a =", a)print("b =", b)print("c =", c)print("d =", d)考试重点:嵌套结构中浅拷贝只复制外层,内层对象仍共享。
4.9 函数与 lambda#
def add(x, y): return x + y
add_lambda = lambda x, y: x + y
salaries = {"Alex": 100000, "Bob": 20000, "Cindy": 50000}richest = max(salaries, key=lambda name: salaries[name])print(richest)lambda 冒号前是输入,冒号后是输出表达式;复杂逻辑应使用 def。
4.10 pandas Series 与 DataFrame#
# 根据课程内容整理的通用模板import pandas as pd
s = pd.Series([90, 85, 88], index=["Alice", "Bob", "Cindy"])
df = pd.DataFrame({ "name": ["Alice", "Bob", "Cindy"], "score": [90, 85, 88], "class": ["A", "A", "B"]})
print(df.head())print(df["score"].mean())Series 是一维带索引数据;DataFrame 是二维表格数据。具体 pandas 操作在后续课程展开。
4.11 文本向量化与相似度#
# 根据课程内容整理的通用模板from sklearn.feature_extraction.text import CountVectorizerfrom sklearn.metrics.pairwise import cosine_similarity
texts = [ "data analysis is useful", "data mining and analysis are important"]
vectorizer = CountVectorizer(stop_words="english")X = vectorizer.fit_transform(texts)sim = cosine_similarity(X[0], X[1])print(sim[0][0])print(vectorizer.get_feature_names_out())输入是文本列表,输出是文本相似度。真实任务中还需分词、去停用词、词形归一。
4.12 用户聚类模板#
# 根据课程内容整理的通用模板import pandas as pdfrom sklearn.preprocessing import StandardScalerfrom sklearn.cluster import KMeans
df = pd.DataFrame({ "night_activity": [0.1, 0.8, 0.2, 0.9], "avg_speed": [5, 40, 6, 35], "app_usage": [2, 8, 3, 9]})
X = df[["night_activity", "avg_speed", "app_usage"]]scaler = StandardScaler()X_scaled = scaler.fit_transform(X)
model = KMeans(n_clusters=2, random_state=42, n_init="auto")df["cluster"] = model.fit_predict(X_scaled)print(df)用途:模拟移动用户画像与用户分群。易错点:量纲不同要标准化;聚类标签需要业务解释。
5. 图表/方法选择指南#
| 数据/问题类型 | 典型问题 | 推荐方法 | 推荐图表 | Python 工具 |
|---|---|---|---|---|
| 新表格数据 | 数据有多少行列?缺失多吗?变量分布怎样? | 探索式数据分析 EDA | 直方图、箱线图、散点图、相关矩阵 | pandas, matplotlib, seaborn |
| 购物篮/交易数据 | 哪些商品经常一起出现? | 关联规则挖掘 | 共现网络、规则表 | pandas;FP-growth 思想 |
| 连续变量预测 | 搜索量能否预测流感趋势? | 回归 | 散点图 + 回归线 | statsmodels, sklearn |
| 用户行为数据 | 用户有哪些类型? | 特征工程 + 聚类 | 聚类散点图、热力图 | pandas, sklearn |
| 时间位置数据 | 用户生活规律、通勤模式 | 轨迹分析、统计描述、聚类 | 地图、时间热力图 | pandas;材料未展开地图包 |
| 文本数据 | 文本是否相似?主题是什么? | 分词、去停用词、向量化、相似度 | 词云、关键词网络、主题分布 | sklearn;材料未展开 jieba |
| 论文/引文数据 | 学科结构、核心作者、知识扩散 | 网络分析、共词/共引 | 网络图 | networkx |
| 图像/视频数据 | 图中是否有人?人在做什么? | 图像识别、动作识别 | 图片标注、视频帧分析 | OpenCV/深度学习;材料未展开 |
| 聊天记录数据 | 什么时候聊得多?情绪如何? | 时间统计、情感分析 | 日历热力图、小时分布图 | pandas, matplotlib, seaborn |
| 多指标评价 | 行业景气程度如何? | 指标体系 + 加权汇总 | 雷达图、柱状图、趋势图 | pandas, numpy |
6. 公式与指标总结#
| 指标/公式 | 公式 | 符号含义 | 适用条件 | 直观解释 | 考试易错点 |
|---|---|---|---|---|---|
| 回归预测 | y = f(x) + ε | x 为自变量或特征;y 为预测目标;ε 为误差。 | 有历史样本,希望预测连续型结果。 | 用过去数据拟合关系,对新样本预测。 | 回归预测连续值,不是类别。 |
| 文本词袋向量 | x = (x1, x2, …, xn) | xi 表示第 i 个词是否出现或出现次数。 | 需要将文本转为数值向量。 | 构造词表后,用数字表示每篇文本。 | 词袋忽略词序;词形变化需归一。 |
| 余弦相似度 | cos(θ) = (x·y)/(||x|| ||y||) | x、y 为两个文本或对象向量。 | 比较两个向量方向是否相似。 | 方向越接近,相似度越高。 | 关注方向,不直接关注绝对长度。 |
| 欧氏距离 | d(x,y)=sqrt(sum((xi-yi)^2)) | xi、yi 为两个样本在第 i 维的取值。 | 衡量数值向量之间距离。 | 多维空间中两点直线距离。 | 受变量尺度影响,常需标准化。 |
| 多指标加权汇总 | S = sum(wi xi) | S 为综合得分;xi 为指标;wi 为权重。 | 景气指数、综合评价。 | 多个维度按重要性合成总分。 | 指标量纲不同要先标准化;权重要有依据。 |
材料说明:本讲是课程导论与语法回顾,数学公式较少;上表主要根据课堂案例抽象整理。
作业迟交扣分规则(课程规则)#
| 迟交时间 | 扣分 |
|---|---|
| 24 小时以内 | 该次作业总分扣 20% |
| 48 小时以内 | 该次作业总分扣 40% |
| 72 小时以内 | 该次作业总分扣 60% |
| 96 小时以内 | 该次作业总分扣 80% |
| 超过 96 小时 | 该次作业不计入总分 |
7. 课堂重点与考试提示#
7.1 必背概念#
- 本课程不是语法课:重点是数据分析理论与实践,Python 是工具。
- 数据分析没有简单对错,更多看好坏、适合程度和解释质量。
- 用户画像是用行为数据构造特征向量,而不是识别真实身份。
- 回归用于连续值预测;分类用于类别预测。
- list 可变,tuple 不可变;dict 是 key-value;set 无序且不重复。
- 列表推导式一次性生成列表;生成器表达式惰性计算,通常只能遍历一次。
- 赋值、浅拷贝、深拷贝是高频代码阅读考点。
- Series 一维,DataFrame 二维表格。
7.2 必会代码#
| 类别 | 必须熟悉的写法 |
|---|---|
| 条件判断 | if / elif / else |
| 循环 | for i in range(…); while condition |
| 循环控制 | break / continue / pass |
| 切片 | seq[start:end |
| 推导式 | [x**2 for x in range(10)] |
| 生成器 | (x**2 for x in range(10)) |
| 拷贝 | copy.copy(); copy.deepcopy() |
| 函数 | def; lambda |
| 常用导包 | import numpy as np; import pandas as pd; import matplotlib.pyplot as plt; import seaborn as sns |
7.3 必会分析思路#
| 场景 | 答题步骤 |
|---|---|
| 给一份新数据 | 明确问题 → 查看结构 → 缺失/异常处理 → 描述统计 → 可视化 → 选择方法 → 解释结果 |
| 用户画像 | 收集行为数据 → 构造特征 → 标准化 → 聚类/分类 → 标签解释 → 应用 |
| 文本相似度 | 分词 → 去停用词 → 词形归一 → 向量化 → 计算相似度 → 解释结果 |
| 网络分析 | 定义节点和边 → 构建网络 → 计算结构指标 → 识别核心/边缘 → 解释关系含义 |
| 客户流失预警 | 定义流失标签 → 构造历史特征 → 训练模型 → 预测风险 → 制定干预策略 |
7.4 高频易错点#
- 把 b = a 当成复制对象。
- 混淆浅拷贝和深拷贝。
- 忘记切片右端不包含。
- 把生成器表达式当成 tuple。
- 第二次遍历生成器时还期待有输出。
- 过度依赖 AI 写代码,但不能判断代码是否正确。
- 把相关关系解释成因果关系。
- 只画图不解释图。
- 数据分析只追求复杂模型,不关注需求。
- 混淆 seaborn 和 matplotlib 的定位。
7.5 可能出题方式#
| 题型 | 可能问法 |
|---|---|
| 概念题 | 为什么本课程不是语法课?Series 与 DataFrame 的区别?list 与 tuple 的区别? |
| 代码阅读题 | 判断浅拷贝/深拷贝输出;生成器第二次遍历;切片结果。 |
| 代码补全题 | 列表推导式、lambda 找最大值、常见导包。 |
| 分析应用题 | 如何用移动电信数据构建用户画像?如何用搜索数据预测流感?如何分析聊天记录? |
8. 期末复习版精简笔记#
| 主题 | 必须记住的内容 |
|---|---|
| 课程核心 | Python 是工具,数据分析是目标;不要死记函数,要会查、会用、会解释。 |
| 数据分析评价 | 是否合理、是否满足需求、是否解释清楚,而不是代码越复杂越好。 |
| 典型案例 | 啤酒与尿布=关联规则;Google 流感=搜索数据+回归;用户画像=行为特征+聚类;知识图谱=节点+边。 |
| 基础语法 | if/elif/else;for/while;break/continue/pass;seq[start:end |
| 数据结构 | list 可变;tuple 不可变;dict 键值对;set 无序不重复。 |
| 推导式/生成器 | 列表推导式生成 list;生成器表达式惰性计算、节省内存、通常只能遍历一次。 |
| 拷贝 | b=a 不复制;浅拷贝复制外层;深拷贝递归复制全部。 |
| 工具包 | NumPy=ndarray;pandas=Series/DataFrame;matplotlib=灵活;seaborn=快速统计图;sklearn=机器学习。 |
9. 自测题与参考答案
一、选择题#
| 题号 | 题目 | 答案 | 解析 |
|---|---|---|---|
| 1 | 本课程最核心的定位是? A. 系统学习 Python 语法细节 B. 使用 Python 作为工具学习数据分析方法 C. 算法竞赛训练 D. 环境配置 | B | PPT 与课堂均强调“本课程不是语法课”,重点是数据分析理论与实践。 |
| 2 | 关于 list 和 tuple,正确的是? A. list 不可变 B. tuple 可变 C. list 可变,tuple 不可变 D. tuple 不能存多个元素 | C | list 是可变有序序列,tuple 是不可变有序序列。 |
| 3 | 关于生成器表达式,错误的是? A. 使用圆括号 B. 返回 generator object C. 通常只能遍历一次 D. 返回 tuple | D | 生成器表达式不是 tuple。 |
| 4 | 快速绘制统计图且不做大量细节定制,优先考虑? A. seaborn B. copy C. os D. random | A | seaborn 适合快速绘制统计图,matplotlib 更灵活。 |
二、判断题#
| 题号 | 题目 | 答案 | 解析 |
|---|---|---|---|
| 5 | 数据分析结果只有绝对正确和绝对错误两种。 | 错 | 数据分析更看重合理性、适用性和解释质量。 |
| 6 | range(1, 5) 会生成 1、2、3、4、5。 | 错 | range 左闭右开,不包含 5。 |
| 7 | deepcopy 会递归复制嵌套对象,因此原对象内部 list 被修改不会影响深拷贝结果。 | 对 | 深拷贝复制父对象和子对象。 |
三、简答题#
| 题号 | 题目 | 参考答案 |
|---|---|---|
| 8 | 为什么说“用户画像不是画脸”? | 用户画像是用位置、通话、App 使用、消费等行为数据构造特征向量,从而刻画生活规律、兴趣偏好和行为模式;不一定识别真实身份。 |
| 9 | 简述 Google 流感预测的分析逻辑。 | 将用户搜索发烧、咳嗽等症状词的行为数据与历史流感数据结合,建立回归或预测模型,用当前搜索行为预测流感趋势。 |
| 10 | list、tuple、dict、set 的核心区别是什么? | list 可变有序;tuple 不可变有序;dict 是 key-value 且 key 唯一;set 无序且元素不重复。 |
四、代码阅读题#
- 阅读代码,写出输出结果并解释。
name = "ABCDEF"print(name[1:-1])print(name[::-2])答案:BCDE;FDB。解析:name[1:-1] 从索引 1 到倒数第 1 个之前;name[::-2] 从末尾反向每隔 2 个取一个。
- 阅读代码,判断 b、c、d 的输出。
import copy
a = [[1, 2], [3, 4]]b = ac = copy.copy(a)d = copy.deepcopy(a)
a[0].append(99)a.append([5, 6])
print(b)print(c)print(d)答案:b 为 [[1,2,99],[3,4],[5,6]];c 为 [[1,2,99],[3,4]];d 为 [[1,2],[3,4]]。解析:b 与 a 完全共享;c 外层独立但内层共享;d 完全独立。
五、代码补全题#
| 题号 | 题目 | 答案与解析 |
|---|---|---|
| 13 | 用列表推导式生成 0 到 9 中偶数的平方:result = [____ for x in range(10) if ____] | result = [x ** 2 for x in range(10) if x % 2 == 0]。表达式为平方,条件为偶数筛选。 |
| 14 | 找出工资最高的人:richest = max(salaries, key=____) | key=lambda name: salaries[name]。max 默认比较 key,加 key 后按工资值比较。 |
| 15 | 补全导包:numpy/pandas/matplotlib/seaborn 的惯用别名 | import numpy as np; import pandas as pd; import matplotlib.pyplot as plt; import seaborn as sns。 |
六、数据分析应用题#
| 题号 | 题目 | 答题步骤 |
|---|---|---|
| 16 | 给定移动电信数据,如何构建用户画像? | 明确目标 → 构造位置、时间、速度、通话、App 使用特征 → 清洗与标准化 → 聚类/分类 → 解释用户标签 → 应用于推荐、服务或预警。 |
| 17 | 如何分析一段微信聊天记录? | 整理字段 → 统计每天/每小时消息数和发送者比例 → 绘制日历热力图与小时分布 → 分词、高频词、情感分析 → 解释互动规律。 |
| 18 | 如何比较两篇论文摘要是否相似? | 分词 → 去停用词 → 词形归一 → 构造词袋或 TF-IDF 向量 → 计算余弦相似度或距离 → 解释相似程度。 |
10. 一页纸考前速览#
| 考前 10 分钟检查项 | 最核心内容 |
|---|---|
| 课程定位 | 不是语法课;Python 是工具,数据分析是目标。 |
| 典型案例 | 啤酒与尿布=关联规则;Google 流感=回归预测;用户画像=行为特征+聚类;知识图谱=网络。 |
| 切片 | seq[start:end |
| 循环控制 | break 退出整个循环;continue 跳过本轮;pass 占位。 |
| 数据结构 | list 可变有序;tuple 不可变有序;dict 键值对;set 无序去重。 |
| 推导式 | [expr for x in iterable if cond] 生成 list。 |
| 生成器 | (expr for x in iterable if cond) 惰性计算,通常只能遍历一次。 |
| 拷贝 | b=a 不复制;copy.copy 浅拷贝;copy.deepcopy 深拷贝。 |
| 函数 | def 适合完整函数;lambda 适合简短表达式。 |
| 常用包 | np、pd、plt、sns 是惯用别名;NumPy 数组、pandas 表格、matplotlib/seaborn 画图、sklearn 机器学习。 |
| 高危错误 | 相关不等于因果;画图后必须解释;生成器不是 tuple;浅拷贝嵌套对象共享。 |
材料中未充分说明:NumPy ndarray 的具体 API、pandas 数据清洗/聚合细节、可视化参数、机器学习具体算法、网络指标、图像和文本的完整建模流程。这些内容应结合后续 PPT 与课堂转录继续补充。
第 2 章 pandas 数据结构与基础操作#
内容来源:原文件内容。 课程 PPT《第 1 章 Python 数据分析基础 II》与 2026-03-16 课堂转录。
1. 本讲/本章知识框架#
本章围绕 Pandas 的两类核心数据结构展开:先理解 Series/DataFrame 与索引,再学习选择、对齐、统计、缺失值和层次化索引。课堂转录进一步强调:统计方法本质是把高维数据规约为少量统计量,axis、skipna、level 与 index_col 等参数是代码题的高频控制点。
-
- Pandas 定位
- 基于 NumPy;提供带标签轴的数据结构、数据对齐、缺失值处理、关系操作和时间序列能力。
-
- Pandas 数据结构
- Series:一维带索引数据;类似“定长、有序字典”。
- DataFrame:二维表格结构;每列可看作共享索引的 Series。
- Index:保存轴标签和元数据;具有不可变性,可重复。
-
- 基本功能
- reindex:按新索引重排并可能引入 NaN。
- drop:删除行/列。
- 索引、选择和过滤:[], loc, iloc, 布尔筛选。
- 算术和数据对齐:按标签自动对齐,未匹配位置为 NaN 或由 fill_value 填充。
- 函数应用和映射:apply、applymap、map。
- 排序与排名:sort_index、sort_values、rank。
-
- 描述性统计
- 汇总统计:sum、mean、min、max、idxmax/idxmin、cumsum。
- describe:快速查看连续/离散变量统计。
- 相关性与协方差:corr、cov、corrwith。
- 唯一值、计数和成员判断:unique、value_counts、isin、get_indexer。
-
- 缺失值处理
- 检测:isnull/notnull。
- 删除:dropna,how、axis、thresh。
- 填充:fillna,常数、字典、method、limit、inplace;均值等统计量填充。
-
- 层次化索引
- MultiIndex:在一个轴上有多个索引级别,用低维表表达高维数据。
- 选择与重塑:部分索引选择、stack/unstack。
- 级别操作:swaplevel、sort_index(level=…)、按 level 汇总。
- 索引与列互转:set_index、reset_index。
-
- 课堂转录补充:数据读写
- Python 内置 open/read/readline/readlines/write/close。
- Pandas 读数据:read_csv、read_table、read_fwf、read_clipboard、read_excel 等。
- 常用参数:sep、header、names、index_col、路径、正则分隔符 r”\s+“。
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| Pandas | Pandas / Python Data Analysis Library | 基于 NumPy 的数据分析工具,提供带标签轴的数据结构与便捷函数。 | 表格数据、缺失值、数据对齐、统计分析。 | 不是 NumPy 的替代,而是在 NumPy 基础上增加索引与表格操作。 | 为什么 Pandas 适合数据分析? |
| Series | Series | 一维类似数组对象,由 values 与 index 组成。 | 单列变量、时间序列、键值映射。 | 不是普通 list;它保留索引和值的关联。 | 说明 Series 的组成及默认索引。 |
| DataFrame | DataFrame | 二维表格结构,含行索引和列索引,各列可为不同类型。 | CSV/Excel 表格、样本-变量矩阵。 | 可视为共享行索引的 Series 字典;列选择返回视图需谨慎。 | DataFrame 与 Series 的关系是什么? |
| 索引 | Index | Pandas 坐标轴标签及元数据对象。 | 标签选择、对齐、重排、层次化索引。 | Index 不可变,但可以整体替换;索引可重复。 | 为什么 Index 设计为不可变? |
| 重新索引 | reindex | 使对象符合新索引,缺失标签处生成 NaN,可指定填充方法。 | 调整行列顺序、补齐时间序列。 | reindex 不是就地排序;新标签会引入缺失值。 | reindex 与 sort_index 区别? |
| 标签选择 | loc | 按行/列标签进行选择。 | 已知 index/columns 名称时。 | 标签切片通常包含结束端点;与 Python 位置切片不同。 | loc 与 iloc 如何区别? |
| 位置选择 | iloc | 按整数位置进行选择。 | 已知行列下标时。 | 遵循 Python 切片规则:不含结束端点。 | iloc[1<3>3>] 选到哪几行? |
| 自动对齐 | Automatic alignment | Pandas 算术运算按索引标签匹配,而非仅按位置相加。 | 不同来源数据合并计算。 | 未匹配标签产生 NaN;可用 fill_value。 | 两个 Series 相加时索引不一致怎么办? |
| 归约 | Reduction | 把一行/一列/一组数据压缩为一个或少量统计量。 | sum、mean、min、max、std、describe。 | axis 决定被规约的方向,而结果保留另一轴标签。 | df.sum(axis=0/1) 分别返回什么? |
| 缺失值 | NaN / NA | 表示数据缺失;None 也常被当作缺失处理。 | 真实数据预处理、统计前清洗。 | 很多统计方法默认 skipna=True;不等于 0。 | NaN 在 sum/mean 中默认如何处理? |
| describe | describe | 一次性输出常用描述统计。 | 拿到数据后快速了解分布。 | 数值型与非数值型结果不同:数值给均值/分位数,离散给 unique/top/freq。 | describe 对离散变量返回哪些统计量? |
| idxmax/idxmin | idxmax / idxmin | 返回最大/最小值对应的索引标签。 | 找最高分学生、销量最大门店。 | max 返回值,idxmax 返回标签。 | 如何找到最大销量对应的门店? |
| 相关系数 | Correlation | 衡量两个变量线性相关程度。 | 股票收益率、变量关系分析。 | 相关不等于因果;需对齐并排除 NaN。 | corr、corrwith 的使用场景? |
| 唯一值 | unique | 返回序列中不重复的值。 | 类别变量取值集合。 | 顺序通常按首次出现顺序;课堂强调可预期。 | unique 的返回顺序如何理解? |
| 计数 | value_counts | 统计各唯一值出现次数,通常按频数降序。 | 类别分布、柱状图数据。 | 可作为 Series 方法,也可 pd.value_counts;传函数给 apply 时不要加括号。 | 如何统计每列类别频数? |
| 成员判断 | isin | 向量化判断元素是否属于给定集合。 | 筛选某些类别或编码。 | 返回布尔 Series/DataFrame,可用于布尔索引。 | 如何筛选省份在列表中的行? |
| dropna | dropna | 删除缺失值。 | 缺失较少或缺失行不可用时。 | DataFrame 默认删除任何含缺失值的行,非常严格。 | dropna(how=“all”) 与默认区别? |
| fillna | fillna | 填充缺失值。 | 缺失值需要保留样本时。 | 默认返回新对象;inplace=True 才原地修改。 | 如何用均值填充某列? |
| 层次化索引 | Hierarchical indexing / MultiIndex | 一个轴上有多个索引级别。 | 多维数据、分组汇总、透视表、面板式数据。 | 外层+内层组合若唯一,可自然 unstack 成 DataFrame。 | MultiIndex 如何表达高维数据? |
| stack/unstack | stack / unstack | Series/DataFrame 与层次化索引之间的重塑操作。 | 长表/宽表转换。 | unstack 将内层索引旋到列;stack 是逆操作。 | 何时使用 unstack? |
| set_index/reset_index | set_index / reset_index | 列与索引之间相互转换。 | 把分组字段转为索引,或还原为普通列。 | set_index 默认 drop=True;reset_index 会把索引层放到前面的列。 | 如何保留被设为索引的原列? |
| read_csv | read_csv | 读取逗号分隔文件为 DataFrame。 | 最常见的数据导入。 | 默认把第一行作为列名,生成 RangeIndex 行索引。 | 无表头 CSV 应如何读取? |
| sep | separator | 指定字段分隔符。 | 逗号、制表符、多空格分隔文件。 | read_table 默认制表符;read_csv 也可指定 sep。 | 如何读取空格数不固定的文本表? |
| index_col | index_col | 读取时指定某列或多列作为行索引。 | 把 ID/时间/层次字段作为索引。 | 指定列必须在读取后的列范围内;可传列表构造层次索引。 | names 与 index_col 的先后关系? |
3. 重点知识详解#
本节按“概念定义—直观理解—PPT对应内容—老师课堂强调—典型例子—可能考点—常见错误”组织。页码为 PPT 页码;时间为课堂转录中的大致时间。
3.1 Pandas 的定位:带标签的数据分析工具#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Pandas 是基于 NumPy 的数据分析库,提供 Series、DataFrame 等带标签轴的数据结构,支持数据对齐、缺失值处理、关系操作和统计计算。 |
| 直观理解 | NumPy 擅长数值数组;Pandas 在数组上加了“行名/列名”和表格语义,使不同来源的数据能按标签安全合并、筛选和统计。 |
| PPT 中对应内容 | PPT 第 2-4 页:Pandas 简介、本节内容。 |
| 老师课堂强调 | 课堂主要从描述性统计开始,但反复强调“知道有这个功能、能调用、通过练习掌握”。 |
| 典型例子 | 拿到学生成绩表后,不需要手写循环,可用 df.mean(), df.describe(), df.isnull() 等快速分析。 |
| 可能考点 | 概念题:说明 Pandas 为什么适合数据分析;代码题:导入 pandas 并构造 Series/DataFrame。 |
| 常见错误 | 把 Pandas 当成普通二维列表;忽略索引导致按位置误算。 |
3.2 Series:一维数据 + 索引#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Series 是一维类似数组的对象,包含数据 values 与索引 index。若不指定 index,默认生成 0 到 N-1 的 RangeIndex。 |
| 直观理解 | Series 可以看作“有顺序的字典”:index 是键,values 是值。 |
| PPT 中对应内容 | PPT 第 8-20 页:Series 定义、values/index、index 参数、按标签选择、布尔过滤、字典构造、自动对齐、name 属性。 |
| 老师课堂强调 | 本节课堂转录未重点讲 Series 基础,属于 PPT 主线内容。 |
| 典型例子 | pd.Series([4,7,-5,3], index=[“d”,“b”,“a”,“c”]) 后,可用 s[“a”] 取值,也可用 s[s>0] 过滤。 |
| 可能考点 | 解释 Series 的 values 与 index;给定字典和 index 构造 Series 并说明 NaN 的来源;判断两个 Series 相加结果。 |
| 常见错误 | 以为 Series 运算按位置匹配;忘记给定 index 会触发数据对齐,缺失标签变 NaN。 |
3.3 DataFrame:二维表格与列视图#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | DataFrame 是二维表格数据结构,含行索引和列索引;每列可有不同类型,可视为共享行索引的 Series 字典。 |
| 直观理解 | 每行通常代表一个样本,每列代表一个变量;DataFrame 是课程后续统计、清洗、读写的主对象。 |
| PPT 中对应内容 | PPT 第 21-36 页:DataFrame 定义、head、columns 指定、列/行选择、列赋值、删除列、嵌套字典构造、values 属性。 |
| 老师课堂强调 | 课堂在描述性统计中明确强调“常见思维方式是每一行代表一个样本,每一列代表一个维度”(约 12<38>38>)。 |
| 典型例子 | df[“state”] 选择列;df.loc[“three”] 按标签取行;del df[“debt”] 删除列。 |
| 可能考点 | 构造 DataFrame;解释列赋值长度要求;说明 df[“col”] 与 df.loc[row] 的含义。 |
| 常见错误 | 用属性访问列名时列名含空格或与方法重名;通过 df[col] 得到的列可能是视图,就地修改会影响原 DataFrame。 |
3.4 Index 与 reindex/drop:轴标签管理#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Index 保存坐标轴标签及元数据,不可变,可重复;reindex 按新索引重排,drop 删除指定轴标签。 |
| 直观理解 | Index 是 Pandas 自动对齐和标签选择的基础。reindex 是“按新名单重新排队”,drop 是“从名单里删除”。 |
| PPT 中对应内容 | PPT 第 37-42 页、48-60 页:索引对象、不可变性、集合操作、reindex、drop、inplace。 |
| 老师课堂强调 | 课堂后半段提到 set_index/reset_index 时强调 RangeIndex 是默认索引,设新索引会覆盖默认索引(约 1:23<50>50>)。 |
| 典型例子 | s.reindex([“a”,“b”,“c”,“d”]);df.drop(“two”) 删除行;df.drop(“state”, axis=“columns”) 删除列。 |
| 可能考点 | 问 reindex 可能引入什么;drop 删除列应如何指定 axis;inplace=True 的返回值问题。 |
| 常见错误 | 把 reindex 当作排序;drop 列时漏写 axis=1/“columns”;误以为 inplace=True 会返回新对象。 |
3.5 索引、选择与过滤:[], loc, iloc, 布尔条件#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Pandas 支持按列名、标签、位置和布尔数组进行数据选择。loc 按标签,iloc 按整数位置。 |
| 直观理解 | 选择题和代码题常考“你到底是在按标签选,还是按位置选”。 |
| PPT 中对应内容 | PPT 第 61-70 页:Series 索引、标签切片、DataFrame 列选择、布尔筛选、loc/iloc、小结。 |
| 老师课堂强调 | 课堂没有详细展开这一块,但后续统计和缺失值处理均依赖这些选择方式。 |
| 典型例子 | df.loc[“b”:“d”, [“one”,“two”]];df.iloc[1<3>3>, 0<2>2>];df[df[“score”] >= 60]。 |
| 可能考点 | 给定 DataFrame 判断 loc/iloc 输出;写布尔筛选表达式。 |
| 常见错误 | 标签切片包含终点而位置切片不包含终点;df[“a”:“c”] 对行切片与 df[[“a”,“c”]] 选列容易混。 |
3.6 算术和数据对齐:按标签匹配#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Series/DataFrame 算术运算默认按索引和列标签对齐;缺失匹配产生 NaN,可使用 add/sub 等方法的 fill_value。 |
| 直观理解 | Pandas 不只是把第 1 个数加第 1 个数,而是先看标签是否对应。 |
| PPT 中对应内容 | PPT 第 71-82 页:Series/DataFrame 自动对齐、带填充值的算术方法、DataFrame 与 Series 运算。 |
| 老师课堂强调 | 在描述性统计前,老师将“数据对齐”和“比较筛选复原”与索引联系起来(约 30<05>05>)。 |
| 典型例子 | s1 + s2 会按 index 合并;df1.add(df2, fill_value=0) 可避免未匹配位置直接 NaN;df - df.iloc[0] 按列广播。 |
| 可能考点 | 给两个索引不同的 Series,写出相加结果;解释 DataFrame 与 Series 默认按列匹配。 |
| 常见错误 | 用 fill_value 仍需注意两个对象都缺失的位置仍可能 NaN;DataFrame 与 Series 想按行广播时忘记 axis 参数。 |
3.7 apply/map/applymap、排序与排名#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | apply 将函数应用到 DataFrame 的某个轴;map 作用于 Series;applymap 作用于 DataFrame 的每个元素。sort_index/sort_values 排序,rank 排名。 |
| 直观理解 | 当内置统计不够用时,把自定义函数“交给 Pandas”沿行或列执行。 |
| PPT 中对应内容 | PPT 第 83-96 页:ufunc、apply、返回 Series、applymap/map、排序与排名、重复索引。 |
| 老师课堂强调 | 课堂讲 value_counts 的 apply 示例时强调:把函数作为参数传给 apply 时不要加括号(约 40:18-41<14>14>)。 |
| 典型例子 | df.apply(lambda x: x.max()-x.min());s.map(format_func);df.sort_values(by=[“score”,“age”])。 |
| 可能考点 | 判断 apply 默认作用方向;补全 df.apply(pd.value_counts).fillna(0);解释 rank 的并列处理。 |
| 常见错误 | pd.value_counts() 与 pd.value_counts 的区别;axis=0/1 写反;排序索引和排序值混淆。 |
3.8 描述性统计:sum、axis、skipna、describe、idxmax#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | 描述性统计是用统计量概括数据分布,如和、均值、标准差、最大最小、分位数等。 |
| 直观理解 | 老师强调其本质是“数据规约”:把大量样本压缩成少量统计量,便于比较和理解。 |
| PPT 中对应内容 | PPT 第 100-106 页:sum、axis、skipna、idxmax/idxmin、describe、统计方法列表。 |
| 老师课堂强调 | 约 09:19-11<12>12> 强调从 N 个数据变成一个统计量;约 12<38>38> 强调默认按列规约、默认跳过缺失值;约 17<14>14> 强调 describe 很重要。 |
| 典型例子 | 比较两个班成绩可用均值;寻找最高分学生用 scores.idxmax();拿到数据先 df.describe()。 |
| 可能考点 | df.sum() 默认返回什么;axis=“columns” 的结果保留哪一轴;describe 对数值/离散变量分别返回什么;idxmax 与 max 区别。 |
| 常见错误 | axis 理解反:axis=0 表示沿行方向规约,得到每列结果;skipna=True 会忽略缺失值,不代表缺失值为 0。 |
3.9 相关性、协方差与金融例子#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | Series.corr/cov 计算两个序列的相关系数/协方差;DataFrame.corr/cov 返回矩阵;corrwith 计算 DataFrame 与另一 Series/DataFrame 的逐列或逐行相关。 |
| 直观理解 | 把多列变量之间的关系压缩为矩阵,快速观察变量是否同步变化。 |
| PPT 中对应内容 | PPT 第 107-112 页:引入股票数据、pct_change、corr/cov、corrwith。 |
| 老师课堂强调 | 约 27:23-29<28>28> 解释股票收益率相关矩阵,并提醒大数据时应精细化地只算有意义的列。 |
| 典型例子 | prices.pct_change() 得到收益率;returns.corr() 得到股票间相关系数矩阵;returns.corrwith(returns[“IBM”])。 |
| 可能考点 | 写出计算百分比变化和相关矩阵的代码;解释相关系数矩阵的行列含义。 |
| 常见错误 | 把价格相关和收益率相关混为一谈;忽视 NaN 和索引对齐;把相关性解释为因果关系。 |
3.10 唯一值、计数与成员判断#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | unique 返回唯一值;value_counts 统计频数;isin 判断元素是否属于集合;Index.get_indexer 可把重复序列映射到唯一值位置。 |
| 直观理解 | 这些方法服务于类别变量整理、筛选、压缩、恢复和画柱状图前的计数。 |
| PPT 中对应内容 | PPT 第 113-117 页:unique、value_counts、isin、get_indexer、列的柱状图例子。 |
| 老师课堂强调 | 约 30<46>46> 强调 unique 顺序按原数据首次出现;约 32<11>11> 强调 value_counts 常用且好用;约 40<18>18> 解释 apply(pd.value_counts).fillna(0)。 |
| 典型例子 | s.unique(); s.value_counts(); df[df[“品类”].isin([“可乐”,“雪碧”])];df.apply(pd.value_counts).fillna(0)。 |
| 可能考点 | 统计各类别出现次数;解释 value_counts 默认排序;用 isin 筛选特定类别。 |
| 常见错误 | 认为 unique 会自动排序;传给 apply 的函数误写为 pd.value_counts();value_counts 结果的索引就是类别值。 |
3.11 缺失值处理:检测、删除、填充#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | 缺失值处理包括检测 isnull/notnull、删除 dropna 和填充 fillna。Pandas 很多统计方法默认跳过缺失值。 |
| 直观理解 | 先判断缺失在哪里,再决定删除还是填充;删除严格会损失样本,填充需要说明依据。 |
| PPT 中对应内容 | PPT 第 120-133 页:缺失值监测、None 作为 NaN、dropna、how/axis/thresh、fillna、method、limit、均值填充。 |
| 老师课堂强调 | 约 46<58>58> 强调 DataFrame.dropna 默认很严格;约 1:05 |
| 典型例子 | df.dropna(how=“all”) 只删除全空行;df.dropna(thresh=2) 保留至少两个非空值的行;df.fillna({“score”: df[“score”].mean()})。 |
| 可能考点 | 判断 dropna 不同参数结果;补全 fillna 代码;解释 skipna 与 dropna 的差异。 |
| 常见错误 | 未评估缺失机制就随意均值填充;忘记 inplace;把 how=“all” 与 thresh 混淆。 |
3.12 层次化索引:MultiIndex、stack/unstack、level 聚合#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | 层次化索引允许一个轴上有多个索引级别,使 Pandas 能用二维表表达高维数据。 |
| 直观理解 | 把“组别—时间—指标”等多维标签叠在同一轴上,可用于部分选择、重塑和分组汇总。 |
| PPT 中对应内容 | PPT 第 135-148 页:MultiIndex 构建、选择、unstack/stack、swaplevel、sort_index(level=)、按 level 汇总、set_index/reset_index。 |
| 老师课堂强调 | 约 1:13-1<16>16> 强调外层+内层配对无重复时能自然展开为 DataFrame;约 1:20-1<26>26> 强调 set_index/reset_index 的转换和索引筛选价值。 |
| 典型例子 | s.unstack() 把内层索引变为列;df.swaplevel(0,1).sort_index(level=0);df.set_index([“class”,“student”])。 |
| 可能考点 | 给出 MultiIndex Series,写出选择外层/内层数据;说明 stack/unstack 方向;补全 set_index/reset_index。 |
| 常见错误 | 层级顺序混乱;忘记 sort_index;set_index 默认删除原列;reset_index 后索引层作为前列出现。 |
3.13 数据读写:open 与 pandas.read_*#
| 项目 | 整理内容 |
|---|---|
| 概念定义 | 数据读写是把外部文件读入内存或把内存对象写出文件。课程转录补充了 Python 内置文件操作与 Pandas 读表函数。 |
| 直观理解 | 先看文件长什么样,再选择读取函数和参数。 |
| PPT 中对应内容 | 上传 PPT 末页仅列出“06 其他技巧”,数据读写主要来自课堂转录。 |
| 老师课堂强调 | 约 1:31<46>46> 强调 open 后必须 close;约 1:43-1<46>46> 强调 read_csv 默认第一行为列名并生成 RangeIndex;约 1:52-1<53>53> 说明 sep=r”\s+” 读取一个或多个空格分隔文件。 |
| 典型例子 | pd.read_csv(path); pd.read_csv(path, header=None, names=[…]); pd.read_csv(path, index_col=“message”); pd.read_table(path, sep=r”\s+”)。 |
| 可能考点 | 根据文件是否有表头选择 header/names;指定单列/多列索引;说明 read_csv 与 read_table 的默认分隔符差异。 |
| 常见错误 | 文件路径与代码运行目录不一致;index_col 指定的列不在读取后的列名中;多空格文件未使用正则分隔符。 |
4. Python 实现与代码模板#
以下代码为“根据课程内容整理的通用模板”。输入、输出和易错点写在每段模板前后。实际考试中应根据题目给出的变量名、列名和文件路径调整。
4.1 导入与构造测试数据#
输入:无或来自 list/dict。输出:Series/DataFrame。用途:复现 PPT 中的基本对象。
import numpy as npimport pandas as pdfrom pandas import Series, DataFrame# Series:一维数据 + 索引s = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])# DataFrame:每行通常是样本,每列通常是变量df = pd.DataFrame( [[1.40, np.nan], [7.10, -4.5], [np.nan, np.nan], [0.75, -1.3]], index=['a', 'b', 'c', 'd'], columns=['one', 'two'])print(s.values, s.index)print(df.head())易错点:常见易错:1)Series 默认索引从 0 到 N-1;2)DataFrame 通过 dict 构造时列顺序在不同版本中可能有差异,考试以题目输出为准。
4.2 Series/DataFrame 选择与过滤#
输入:Series 或 DataFrame。输出:子集对象。用途:按标签、位置、条件筛选。
# Series 选择s['a'] # 单个标签s[['c', 'a', 'd']] # 多个标签,按给定顺序返回s[s > 0] # 布尔过滤'a' in s # 判断标签是否在 Series 的索引中# DataFrame 选择列、选择行、条件筛选df['one'] # 选择列# df.loc['b'] # 按行标签选择行# df.loc['b':'d', ['one']] # loc 标签切片:通常包含结束端点# df.iloc[1:3, 0:1] # iloc 位置切片:不包含结束端点df[df['one'] > 1] # 布尔筛选行易错点:常见易错:loc 是标签;iloc 是整数位置。标签切片和 Python 切片的结束端点规则不同。
4.3 重新索引、删除与对齐计算#
输入:带索引对象。输出:重排或计算后的对象。用途:管理标签、处理不一致索引。
# 重新索引:新标签不存在时生成 NaNs2 = s.reindex(['a', 'b', 'c', 'd', 'e'])# 删除行/列s_drop = s.drop('a')df_drop_row = df.drop('c')df_drop_col = df.drop('two', axis='columns')# 自动对齐:按索引标签匹配,而不是只按位置s_a = pd.Series([1, 2, 3], index=['a', 'b', 'c'])s_b = pd.Series([10, 20, 30], index=['b', 'c', 'd'])result = s_a + s_b # a 和 d 处为 NaN,b/c 对齐相加# 带填充值的算术方法df_sum = df.add(df, fill_value=0)易错点:常见易错:drop 删除列要指定 axis=1 或 axis=“columns”;fill_value 只填某一侧缺失的标签位置。
4.4 apply / map / applymap#
输入:DataFrame/Series 与函数。输出:按轴或逐元素计算结果。用途:自定义统计或格式转换。
# 按列求极差:默认 axis=0,即每列传给函数range_by_col = df.apply(lambda x: x.max() - x.min())# 按行求极差:axis='columns' 或 axis=1range_by_row = df.apply(lambda x: x.max() - x.min(), axis='columns')# 函数返回 Series:会拼接为 DataFramedef min_max(x): return pd.Series({'min': x.min(), 'max': x.max()})summary = df.apply(min_max)# Series.map:适合元素映射或格式化s_format = s.map(lambda x: f'{x:.1f}')# DataFrame.applymap:逐元素处理fmt = df.applymap(lambda x: f'{x:.2f}' if pd.notnull(x) else 'NA')易错点:常见易错:把函数传给 apply 时写函数名,不要写函数调用。例如 df.apply(pd.value_counts),不是 df.apply(pd.value_counts())。
4.5 描述性统计:axis、skipna、idxmax、describe#
输入:数值型 DataFrame/Series。输出:统计量。用途:快速概括分布、找极值标签。
# 默认按列规约:保留列索引,返回每列之和col_sum = df.sum()# 按行规约:对每一行的所有列求和,保留行索引row_sum = df.sum(axis='columns')# skipna=False:只要参与计算的方向存在 NaN,结果也可能为 NaNrow_sum_strict = df.sum(axis='columns', skipna=False)# 最大值对应的标签:max 是值,idxmax 是标签max_value = df['one'].max()max_label = df['one'].idxmax()# 累计求和cum = df.cumsum()# 一次性描述统计summary = df.describe()# 离散变量 describecat = pd.Series(list('aabc') * 4)cat_desc = cat.describe() # count, unique, top, freq易错点:常见易错:axis=0 可理解为“沿行方向压缩,得到每列结果”;skipna 默认 True,但这不是把缺失值当成 0。
4.6 相关性、协方差与变化率#
输入:多列数值数据。输出:变化率、相关矩阵、协方差矩阵。用途:变量关系分析。
# prices:行是日期,列是股票代码或变量名# returns = prices.pct_change() # 百分比变化率,常用于股票收益率# 两个 Series 的相关性/协方差# corr_ibm_msft = returns['IBM'].corr(returns['MSFT'])# cov_ibm_msft = returns['IBM'].cov(returns['MSFT'])# DataFrame 的相关系数矩阵与协方差矩阵# corr_matrix = returns.corr()# cov_matrix = returns.cov()# 每一列与某一列的相关系数# corr_with_ibm = returns.corrwith(returns['IBM'])易错点:常见易错:pct_change 第一行通常为 NaN;corr/cov 会对齐索引并排除非重叠或 NaN 值。
4.7 unique / value_counts / isin / get_indexer#
输入:类别型 Series 或 DataFrame。输出:唯一值、频数、布尔结果、位置编码。用途:类别统计、筛选、压缩恢复。
obj = pd.Series(list('cadaabbcc'))# 唯一值:通常按首次出现顺序u = obj.unique()# 频数统计:默认按频数降序counts = obj.value_counts()counts_unsorted = pd.value_counts(obj.values, sort=False)# 成员判断 + 筛选mask = obj.isin(['b', 'c'])subset = obj[mask]# 从唯一值索引中查找每个原始值的位置unique_values = pd.Index(['c', 'a', 'b'])codes = unique_values.get_indexer(obj)# 对 DataFrame 每列做 value_counts,用 0 填充未出现类别hist_like = pd.DataFrame({ 'Qu1': [1, 3, 4, 3, 4], 'Qu2': [2, 3, 1, 2, 3], 'Qu3': [1, 5, 2, 4, 4]}).apply(pd.value_counts).fillna(0)易错点:常见易错:unique 不等于排序;value_counts 的结果索引是类别值。apply(pd.value_counts) 中不要给 value_counts 加括号。
4.8 缺失值检测、删除与填充#
输入:含 NaN/None 的 Series 或 DataFrame。输出:布尔标记、清洗后对象。用途:数据清洗。
data = pd.DataFrame({ 'A': [1, np.nan, 3, np.nan], 'B': [4, np.nan, np.nan, np.nan], 'C': [7, np.nan, 9, 10]})# 检测missing_mask = data.isnull()non_missing_mask = data.notnull()# Series 删除缺失值s_clean = data['A'].dropna()# DataFrame 默认:删除任何包含缺失值的行,较严格drop_any = data.dropna()# 只删除全部为缺失值的行drop_all = data.dropna(how='all')# 至少保留 2 个非空值的行drop_thresh = data.dropna(thresh=2)# 按列删除:删除含缺失值的列drop_cols = data.dropna(axis='columns')# 填充:常数、按列字典、均值fill0 = data.fillna(0)fill_dict = data.fillna({'A': 0, 'B': 0.5})fill_mean = data.fillna(data.mean(numeric_only=True))# 前向填充,并限制最多连续填充数量ffill_limit = data.fillna(method='ffill', limit=2)易错点:常见易错:fillna 默认返回新对象;要改原对象需 data.fillna(0, inplace=True)。删除/填充前要说明策略是否合理。
4.9 层次化索引 MultiIndex#
输入:多层索引 Series/DataFrame。输出:选择、重塑、排序、汇总结果。用途:表达高维数据与分组统计。
# 构造多层索引 Seriess = pd.Series( np.arange(7), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c'], [1, 2, 3, 1, 3, 1, 2]])# 外层选择、内层选择s_a = s['a']inner_1 = s.loc[:, 1] # 选择内层索引为 1 的数据# Series <-> DataFrame 重塑wide = s.unstack() # 内层索引转为列long = wide.stack() # 逆操作# DataFrame 两个轴都可有层次化索引df_multi = pd.DataFrame(np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']])# 交换层级、按层级排序swapped = df_multi.swaplevel(0, 1)sorted_df = swapped.sort_index(level=0)# 按某一层级汇总(课程思想:按 level 聚合)summary_by_outer = df_multi.groupby(level=0).sum()summary_by_col_color = df_multi.groupby(level=1, axis=1).sum()# 列与索引互转frame = pd.DataFrame({'a': range(7), 'b': range(7, 0, -1), 'c': ['one','one','one','two','two','two','two'], 'd': [0,1,2,0,1,2,3]})frame2 = frame.set_index(['c', 'd'])frame3 = frame.set_index(['c', 'd'], drop=False)back = frame2.reset_index()易错点:常见易错:set_index 默认 drop=True;reset_index 会把索引层放到最前面的列。新版 pandas 中更推荐 groupby(level=…).sum() 表达按层级汇总,这是对课程 level 聚合思想的通用写法。
4.10 文件读写与 pandas 读表#
输入:文件路径或剪贴板内容。输出:字符串、列表或 DataFrame。用途:把外部数据导入分析流程。
# Python 内置文件写入/追加/读取f = open('test_file.txt', 'w', encoding='utf-8')for i in range(5): f.write(f'hello {i}\n')f.close() # 课堂强调:open 后必须 close# 更推荐的写法:with 会自动关闭文件with open('test_file.txt', 'a', encoding='utf-8') as f: f.write('additional line\n')with open('test_file.txt', 'r', encoding='utf-8') as f: first_20 = f.read(20) # f.readline() # 每次读一行 # f.readlines() # 一次性读所有行,文件很大时慎用# Pandas 读常见表格# df1 = pd.read_csv('examples/ex1.csv')# df2 = pd.read_table('examples/ex1.csv', sep=',')# df3 = pd.read_csv('examples/ex2.csv', header=None)# df4 = pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])# df5 = pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'], index_col='message')# df6 = pd.read_csv('examples/csv_mindex.csv', index_col=['key1', 'key2'])# 一个或多个空白字符作为分隔符,适合不定长空格分隔文本# df_space = pd.read_table('examples/ex3.txt', sep=r'\s+', engine='python')# 从剪贴板读取表格文本# df_clip = pd.read_clipboard()易错点:常见易错:1)相对路径相对于当前工作目录;2)header=None 用于无列名文件;3)index_col 指定的列必须存在于读取后的列名中;4)read_csv 与 read_table 本质差异主要是默认分隔符。
5. 图表/方法选择指南#
| 数据/任务场景 | 优先方法 | 选择理由 | 课堂/考试提示 |
|---|---|---|---|
| 拿到一个新 DataFrame,想快速看分布 | df.describe(); df.head(); df.info()(info 为补充理解) | 先看数据长什么样、类型和缺失情况。 | PPT/课堂重点是 describe;info 未在材料充分说明,作补充理解。 |
| 每行是样本、每列是变量,想按变量求和/均值 | df.sum(); df.mean() | 默认 axis=0,按列统计,保留列索引。 | 老师强调这是常见思维方式。 |
| 想对每个样本跨变量求和/均值 | df.sum(axis=“columns”) | 按行统计,保留行索引。 | axis=1/columns 容易写反。 |
| 想找最大值对应的对象 | s.idxmax(); df.idxmax() | 返回索引标签,不是最大值本身。 | 课堂例子:最高分是谁、销量最大门店。 |
| 类别变量取值和频数 | s.unique(); s.value_counts() | 唯一值和计数。 | value_counts 常用且好用;默认频数降序。 |
| 按集合筛选类别 | s.isin(list); df[df[col].isin(list)] | 返回布尔掩码再筛选。 | 适合一次性筛选多个类别。 |
| 统计每列各类别出现次数,作为柱状图数据 | df.apply(pd.value_counts).fillna(0) | 每列分别计数,未出现类别填 0。 | 函数名不要加括号。 |
| 两个 Series/DataFrame 索引不完全一致但要计算 | s1+s2; df1.add(df2, fill_value=0) | Pandas 先按标签对齐。 | 未匹配位置会 NaN。 |
| 变量之间线性关系 | s1.corr(s2); df.corr(); df.corrwith(s) | 相关系数/相关矩阵。 | 相关不等于因果。 |
| 变量共同波动程度 | s1.cov(s2); df.cov() | 协方差/协方差矩阵。 | 量纲影响大,比较时常看 corr。 |
| 数据存在 NaN,需要删除 | s.dropna(); df.dropna(how/axis/thresh) | 删除缺失值或缺失行列。 | DataFrame 默认删除任何含缺失行,严格。 |
| 数据存在 NaN,需要保留样本 | df.fillna(0); df.fillna(dict); df.fillna(method=“ffill”, limit=2) | 常数/分列/前后向填充。 | 填充依据要合理。 |
| 多维标签数据需要部分选择和重塑 | MultiIndex; stack/unstack; set_index | 用层次化索引表达高维数据。 | 外层/内层顺序影响结果。 |
| 根据某个字段分组汇总 | set_index(field) 后按 level 汇总,或 groupby(level=…)(补充理解) | 字段作为索引后筛选/汇总更自然。 | 课堂强调把属性变索引再聚合。 |
| 读入逗号分隔文件 | pd.read_csv(path) | 默认第一行为列名。 | 若无表头要 header=None。 |
| 读入制表符或空格分隔文件 | pd.read_table(path); pd.read_table(path, sep=r”\s+“) | 固定或不固定空白分隔。 | 多空格需正则 sep。 |
| 读入时把某列或多列作为行索引 | pd.read_csv(path, index_col=“id”); index_col=[“k1”,“k2”] | 单列索引或层次化索引。 | index_col 必须在读入列中。 |
6. 公式与指标总结#
PPT 对描述性统计和相关性/协方差给出方法,未系统展开数学公式。下表中涉及数学表达的部分标注为“补充理解”,用于解释函数含义。考试若偏代码,重点在函数、参数和输出形状。
| 公式/指标 | 表达式 | 符号含义 | 适用条件 | 直观解释 | 计算步骤 | 考试易错点 |
|---|---|---|---|---|---|---|
| 求和 sum | Σ x_i | x_i 为一行/列/序列中的有效值 | 数值变量汇总 | 总量累加;Pandas 默认 skipna=True。 | 选轴 axis;按轴求和;若 skipna=False 且有 NaN,结果可能为 NaN。 | 把缺失值误认为 0;axis 写反。 |
| 均值 mean(补充理解) | x̄ = (Σ x_i)/n | n 为有效值数量 | 比较总体水平,如班级平均分。 | 用一个中心值代表一组数据。 | 先确定是否跳过缺失值。 | 异常值影响均值。 |
| 方差 var / 标准差 std(补充理解) | var = Σ(x_i-x̄)^2/(n-1); std=sqrt(var) | x_i 为样本值 | 衡量离散程度。 | 越大表示波动越大。 | Pandas 默认样本标准差。 | 混淆方差和标准差;忽视 ddof。 |
| 分位数 quantile / describe | Q25, Q50, Q75 | 按从小到大位置确定 | 查看分布、偏态、异常值。 | 25%、50%、75% 分位数反映分布位置。 | df.describe() 自动给出。 | 把 50% 分位数等同于均值。 |
| 累计求和 cumsum | y_t = Σ_{i≤t} x_i | 按行/列顺序累计 | 公交上下车、累计销量、累计收益。 | 每个位置是之前所有变化量的累计结果。 | 注意累计方向 axis。 | 未按时间排序就累计。 |
| 差分 diff | x_t - x_{t-1} | 相邻两个观测值 | 时间序列变化量。 | 后一个值减前一个值。 | 第一项通常 NaN。 | 把差分和百分比变化混淆。 |
| 百分比变化 pct_change | (x_t - x_{t-1}) / x_{t-1} | 相邻值;分母非零 | 股票涨跌幅、增长率。 | 相对变化率。 | 通常先处理缺失和 0。 | 把 0.05 误读为 5 而不是 5%。 |
| 协方差 cov(补充理解) | cov(X,Y)=Σ((x_i-x̄)(y_i-ȳ))/(n-1) | 对齐且非缺失的成对数据 | 变量共同波动方向和程度。 | 同向变动为正,反向为负。 | Series.cov; DataFrame.cov。 | 协方差受量纲影响,不能直接比较不同尺度。 |
| 相关系数 corr(补充理解) | corr(X,Y)=cov(X,Y)/(std_X·std_Y) | 线性关系;成对数据 | 衡量线性相关强度。 | 范围通常 [-1,1];越接近 ±1 线性相关越强。 | Series.corr; DataFrame.corr; corrwith。 | 相关不代表因果;非线性关系可能被低估。 |
| 频数 value_counts | count(v)=# {i: x_i=v} | 类别值 v | 类别分布、柱状图前处理。 | 统计每个唯一值出现次数。 | 默认按频数降序。 | 忘记缺失值是否计入;默认 dropna=True(补充理解)。 |
| 排名 rank | 按大小给 1..n 名次 | 有效数值;并列时按 method | 排序名次、评分排序。 | 把数值转换为名次。 | 关注并列 method、ascending。 | 并列排名规则没有说明就随意判断。 |
| 层级汇总 level 聚合 | 按某一索引级别分组后求 sum/mean 等 | MultiIndex 对象 | 多维数据按组汇总。 | 把索引级别当作分组键。 | 指定 level 或 groupby(level=…)。 | 忘记是行轴还是列轴。 |
7. 课堂重点与考试提示#
根据课堂转录,老师在描述性统计、缺失值、层次化索引和数据读写上讲解较多,尤其强调“知道函数能做什么、怎么调用、常见参数含义”。
| 类别 | 复习要点 |
|---|---|
| 必背概念 | Series = values + index;DataFrame = 二维表格/共享行索引的 Series 字典;Index 不可变且可重复;缺失值 NaN/None;层次化索引 MultiIndex;自动算术对齐。 |
| 必背概念 | 描述性统计是“数据规约”:把大量数据压缩为统计量;axis 决定被规约的方向,结果保留另一轴标签。 |
| 必会代码 | df.sum(); df.sum(axis=“columns”); df.sum(skipna=False); df.describe(); s.idxmax(); df.cumsum(); df.corr(); df.cov(); df.corrwith(s)。 |
| 必会代码 | s.unique(); s.value_counts(); s.isin([…]); df.apply(pd.value_counts).fillna(0)。 |
| 必会代码 | df.isnull(); df.dropna(); df.dropna(how=“all”); df.dropna(thresh=2); df.fillna(0); df.fillna(method=“ffill”, limit=2)。 |
| 必会代码 | s.unstack(); df.stack(); df.swaplevel(); df.sort_index(level=…); df.set_index([…], drop=False); df.reset_index()。 |
| 必会代码 | pd.read_csv(path); pd.read_csv(path, header=None, names=[…]); pd.read_csv(path, index_col=“message”); pd.read_csv(path, index_col=[“K1”,“K2”]); pd.read_table(path, sep=r”\s+”)。 |
| 必会分析思路 | 拿到数据:先看 head/describe/isnull;明确行列含义;确定统计方向;判断缺失处理策略;再做相关性/计数/分组。 |
| 必会分析思路 | 做类别统计:unique 看取值,value_counts 看频数,isin 做筛选,apply(pd.value_counts).fillna(0) 形成每列类别频数表。 |
| 必会分析思路 | 做多维数据:把分组字段 set_index 成层次化索引,再选择、排序、unstack 或按 level 汇总。 |
| 高频易错点 | axis=0/1 与结果标签;skipna 默认 True;dropna 默认删除任何含缺失行;fillna 默认不原地修改。 |
| 高频易错点 | max 是最大值,idxmax 是最大值位置标签;unique 顺序不是按字母排序,而是按首次出现顺序;value_counts 默认按频数降序。 |
| 高频易错点 | apply 传函数不要加括号;read_csv 默认第一行列名;header=None 才表示无表头;index_col 必须是读入后的列名或位置。 |
| 可能出题方式 | 给一个 DataFrame,问 df.sum()、df.sum(axis=“columns”)、df.dropna(how=“all”)、df.fillna(method=“ffill”, limit=2) 的输出。 |
| 可能出题方式 | 给两个索引不一致的 Series/DataFrame,判断相加结果或补写 fill_value。 |
| 可能出题方式 | 给 MultiIndex Series,要求选择外层/内层数据,或写 unstack/stack/set_index/reset_index 代码。 |
| 可能出题方式 | 给 CSV 片段,要求选择 read_csv 参数:sep、header、names、index_col、正则分隔符。 |
8. 期末复习版精简笔记#
- Pandas 的核心价值:在 NumPy 数组上加入行列标签,支持自动对齐、缺失值处理、表格操作和快速统计。
- Series = 一维数据 + index;DataFrame = 二维表格 + 行索引 + 列索引;Index 不可变、可重复,是对齐和选择的基础。
- Series 可以像数组、字典一样使用:s[“a”], s[[“a”,“b”]], s[s>0], “a” in s。字典构造时给定 index 会按 index 对齐,缺失键产生 NaN。
- DataFrame 常用:df.head(), df[“col”], df.loc[“row”], df.iloc[i
, k ], del df[“col”], df[“new”] = value/array/Series。数组赋值长度必须匹配。 - reindex 是按新标签重排,可能引入 NaN;drop 删除行/列,删除列需 axis=1 或 axis=“columns”;inplace=True 通常不返回新对象。
- Pandas 算术运算按标签自动对齐,不匹配处为 NaN;add/sub/div/mul 等可用 fill_value。DataFrame 与 Series 默认按列匹配并向行广播。
- apply:默认按列;axis=“columns” 按行。传函数名不要加括号。Series 用 map,DataFrame 每元素用 applymap。
- 描述性统计是数据规约。df.sum() 默认按列,保留列标签;df.sum(axis=“columns”) 按行,保留行标签。skipna 默认 True。
- describe:数值型返回 count/mean/std/min/25%/50%/75%/max;离散型返回 count/unique/top/freq。拿到新数据可先 describe。
- idxmax/idxmin 返回最大/最小值的索引标签;max/min 返回值。cumsum 做累计;diff 做差分;pct_change 做百分比变化。
- 相关性/协方差:Series.corr/cov;DataFrame.corr/cov;corrwith 计算每行/列与另一个对象的相关。先注意 NaN 和索引对齐。
- 类别方法:unique 看唯一值,value_counts 看频数,isin 做集合筛选,Index.get_indexer 做值到唯一值位置的映射。
- 缺失值:isnull/notnull 检测;dropna 删除;fillna 填充。DataFrame.dropna() 默认删除任何含 NaN 的行;how=“all” 只删全空;thresh 控制非空数量。
- fillna 可填常数、按列字典、均值;method=“ffill”/“bfill” 做前/后向填充;limit 限制最多连续填充数量;默认返回新对象。
- 层次化索引:一个轴多个级别,用低维表表达高维数据。常用 s[“a”], s.loc[:, 1], unstack/stack, swaplevel, sort_index(level=…), set_index/reset_index。
- read_csv 默认第一行是列名、自动生成 RangeIndex;无表头用 header=None;指定列名用 names;指定索引用 index_col;多列索引用列表;多空格分隔用 sep=r”\s+”。
9. 自测题与参考答案
题目尽量贴近 PPT 和课堂讲法。代码题默认已执行 import pandas as pd, import numpy as np。
9.1 选择题#
| 题号 | 题目 | 答案 | 解析 |
|---|---|---|---|
| 1 | 关于 Series,下列说法正确的是? A. 只能存数字 B. 必须显式指定索引 C. 由数据和索引组成 D. 运算只按位置对齐 | C | Series 含 values 与 index;若不指定索引,会生成默认 RangeIndex;运算按标签对齐。 |
| 2 | df.sum() 默认返回什么? A. 每行之和 B. 每列之和 C. 所有元素之和 D. 只统计第一列 | B | 默认 axis=0,即按列规约,保留列索引。 |
| 3 | 要按行求和,应使用:A. df.sum(axis=0) B. df.sum(axis=“columns”) C. df.sum(skipna=False) D. df.describe() | B | axis=“columns” 或 axis=1 表示对每行跨列计算。 |
| 4 | 下列哪个方法返回最大值对应的索引标签? A. max B. argmax C. idxmax D. sort_values | C | idxmax 返回标签;max 返回最大值本身。 |
| 5 | DataFrame.dropna() 默认会:A. 只删除全空行 B. 删除任何含缺失值的行 C. 填充缺失值为 0 D. 删除列 | B | 课堂强调默认很严格,任何含缺失值的行都会被删。 |
| 6 | 读取无表头 CSV 的常用参数是:A. header=None B. index_col=None C. sep=None D. names=None | A | header=None 表示文件没有列名,不把第一行当列名。 |
9.2 判断题#
| 题号 | 判断 | 答案 | 解析 |
|---|---|---|---|
| 1 | Series 的 unique() 通常按唯一值首次出现的顺序返回,而不是自动按字母排序。 | 正确 | 课堂特别强调 unique 的顺序可预期,按原数据首次出现。 |
| 2 | df.sum(skipna=True) 表示把 NaN 当作 0 后再计算。 | 错误 | 更准确地说是跳过缺失值;不要简单理解为 NaN=0。 |
| 3 | fillna 默认会原地修改原对象。 | 错误 | 默认返回新对象,原地修改需 inplace=True。 |
| 4 | loc 按标签选择,iloc 按整数位置选择。 | 正确 | 这是索引题最基本区分。 |
| 5 | set_index([“c”,“d”]) 默认会保留 c、d 两列作为普通列。 | 错误 | 默认 drop=True,会把列移入索引;保留需 drop=False。 |
| 6 | read_table 默认分隔符与 read_csv 完全相同。 | 错误 | read_csv 默认逗号;read_table 默认制表符,可通过 sep 改变。 |
9.3 简答题#
| 题号 | 题目 | 标准答案 | 解析 |
|---|---|---|---|
| 1 | 用标准表述说明 Series 是什么。 | Series 是一维类似数组的 Pandas 对象,由一组数据 values 和与数据对应的标签 index 构成;未显式指定 index 时,会生成默认整数索引。 | 答题必须包含“一维”“数据”“索引/标签”。 |
| 2 | 说明 DataFrame 与 Series 的关系。 | DataFrame 是二维表格结构,含行索引和列索引,可理解为若干共享同一行索引的 Series 组成的字典。 | 注意不是简单二维 list;强调共享索引。 |
| 3 | 为什么说描述性统计是数据规约? | 因为 sum/mean/std/describe 等方法把一列、一行或一组大量观测压缩成一个或少量统计量,用于概括分布、比较总体水平或波动。 | 课堂 09:19-11<12>12> 重点。 |
| 4 | dropna(how=“all”)、dropna(thresh=2) 分别是什么意思? | how=“all” 只删除全部为缺失值的行/列;thresh=2 表示保留至少有 2 个非缺失值的行/列,少于该数量则删除。 | 要写出“非缺失值的最小数量”。 |
| 5 | 层次化索引有什么作用? | 层次化索引允许一个轴上存在多个索引级别,使 Pandas 能在二维结构中表达高维数据,并便于部分选择、stack/unstack 重塑和按 level 汇总。 | 关键词:多个索引级别、高维数据、重塑/汇总。 |
9.4 代码阅读题#
| 题号 | 代码/问题 | 答案 | 解析 |
|---|---|---|---|
| 1 | s1=pd.Series([1,2], index=[“a”,“b”]); s2=pd.Series([10,20], index=[“b”,“c”]); s1+s2 的结果索引和值是什么? | 索引为 a,b,c;a 为 NaN,b 为 12,c 为 NaN。 | Pandas 按标签对齐,只有 b 同时存在。 |
| 2 | df = pd.DataFrame([[1,np.nan],[3,4]], columns=[“x”,“y”]); df.sum(axis=“columns”, skipna=False) 输出大意? | 第一行为 NaN,第二行为 7。 | skipna=False 时一行中有 NaN,结果为 NaN。 |
| 3 | pd.Series(list(“abac”)).value_counts() 的结果含义是什么? | 统计 a,b,c 的频数;a 出现 2 次,b/c 各 1 次,默认按频数降序。 | value_counts 的索引是类别,值是次数。 |
9.5 代码补全题#
| 题号 | 题目 | 参考答案 | 解析 |
|---|---|---|---|
| 1 | 补全:读取无表头 CSV,并指定列名 names。 ___(“ex2.csv”, header=, names=names) | pd.read_csv(“ex2.csv”, header=None, names=names) | header=None 表示没有列名。 |
| 2 | 补全:对 DataFrame 每列做频数统计,并把缺失位置填 0。 df.apply(________).fillna(_) | df.apply(pd.value_counts).fillna(0) | 传函数名不加括号。 |
| 3 | 补全:把 c、d 两列设为层次化索引,但保留原列。 frame.set_index([____, ], drop=) | frame.set_index([“c”, “d”], drop=False) | set_index 默认 drop=True;保留需 False。 |
| 4 | 补全:读取一个或多个空格分隔的文本表。 pd.read_table(path, sep=_______) | pd.read_table(path, sep=r”\s+”, engine=“python”) | 课堂解释 r”\s+” 表示一个或多个空白字符;engine=“python” 为通用兼容写法。 |
9.6 数据分析应用题#
| 题号 | 题目 | 参考答案/答题步骤 | 解析 |
|---|---|---|---|
| 1 | 有一张学生成绩表 df,行是学生,列包括 class、math、python、english。请比较不同班级的 Python 平均成绩,并找出全班 Python 最高分学生。 | 步骤:①检查缺失:df[“python”].isnull().sum();②按班级汇总:df.groupby(“class”)[“python”].mean()(补充理解,若坚持本章索引思路,可 df.set_index(“class”) 后按 level 汇总);③最高分标签:df[“python”].idxmax(),再 df.loc[…] 查看学生信息。 | 课程重点是均值规约和 idxmax 找标签;groupby 属于后续聚合内容,此处标作补充理解。 |
| 2 | 给一份交易明细,列含 user_id、item、quantity。想统计每个商品出现次数,并筛选 item 属于 [“可乐”,“雪碧”] 的记录。 | 代码:counts = df[“item”].value_counts(); sub = df[df[“item”].isin([“可乐”,“雪碧”])]。若要保持首次出现唯一商品,可用 df[“item”].unique()。 | 对应课堂关于购物篮/饮料例子与 value_counts、isin。 |
| 3 | 读取一个 CSV:第一行不是列名,5 列依次为 a,b,c,d,message,并希望 message 作为行索引。 | names=[“a”,“b”,“c”,“d”,“message”]; df=pd.read_csv(path, header=None, names=names, index_col=“message”)。也可先读入再 df.set_index(“message”)。 | 课堂强调 index_col 的列必须在读取后的列名范围内。 |
10. 一页纸考前速览#
| 模块 | 10 分钟速记 |
|---|---|
| 对象 | Series = values + index;DataFrame = 二维表格 + 行索引 + 列索引;Index 不可变、可重复。 |
| 选择 | s[“a”], s[[…]], s[s>0];df[“col”];df.loc[label];df.iloc[pos];df[df[col].isin(list)]。 |
| 对齐 | 运算按标签自动对齐;不匹配为 NaN;用 add/sub/mul/div(fill_value=0)。 |
| axis | df.sum() 默认按列;df.sum(axis=“columns”/1) 按行;结果保留未被规约的轴标签。 |
| 描述统计 | df.describe(); df.sum/mean/std/min/max(); s.idxmax(); df.cumsum(); diff(); pct_change()。 |
| 相关 | s1.corr(s2); s1.cov(s2); df.corr(); df.cov(); df.corrwith(s)。注意 NaN 与对齐;相关不等于因果。 |
| 类别 | s.unique():首次出现顺序;s.value_counts():频数降序;s.isin(list):集合筛选;df.apply(pd.value_counts).fillna(0):每列频数表。 |
| 缺失 | isnull/notnull;dropna 默认删任何含缺失行;how=“all” 只删全空;thresh=n 保留至少 n 个非空;fillna 默认返回新对象;method + limit 控制前/后向填充。 |
| 层次化索引 | MultiIndex;s[outer];s.loc[:, inner];unstack/stack;swaplevel;sort_index(level=…);set_index([…], drop=False);reset_index()。 |
| 读文件 | read_csv 默认首行列名;无表头 header=None;指定列名 names;指定索引 index_col;多索引 index_col=[…]; 多空格 sep=r”\s+“;路径相对当前工作目录。 |
| 最易错 | idxmax ≠ max;loc ≠ iloc;value_counts 传 apply 不加括号;drop 列需 axis;set_index 默认删原列;read_table/read_csv 默认 sep 不同。 |
答题步骤模板:①说明对象结构与行列含义;②选择正确索引/筛选方式;③说明 axis/skipna/dropna/fillna 等关键参数;④给出代码;⑤解释输出形状或业务含义。
附:语音识别修正与材料不足说明#
| 转录词形 | 整理采用 | 说明 |
|---|---|---|
| IIDX index max / ID max | idxmax() | 根据 PPT 与上下文“最大值对应标签”修正。 |
| value class / value columns / viral counts | value_counts() | 上下文为唯一值计数。 |
| job NA / drop NA | dropna() | 上下文为删除缺失值。 |
| feel NA / QNA | fillna() | 上下文为缺失值填充。 |
| sack / step / sap | sep | 上下文为 read_csv/read_table 的分隔符参数。 |
| message | message 列名 | 课堂例子中作为 index_col 的列名;若原始课件另有拼写,以原文件为准。 |
| panda state reader | pandas-datareader / pandas_datareader(可能为转录误差) | 课堂提到安装读金融数据的包;该部分非本资料考试主线。 |
| YFPDR override | yf.pdr_override()(可能为转录误差) | 课堂提到 yfinance 与 pandas_datareader 连接修正,材料中未充分说明。 |
材料中未充分说明:上传 PPT 的最后仅出现“06 其他技巧”目录页,数据读写部分主要依据课堂转录整理;若后续提供“数据读写”PPT,可进一步补充 read_json、read_excel、to_csv、to_excel、分块读取等完整内容。
第 3 章 数据读写 清洗 聚合与分组#
内容来源:原文件内容。 课程 PPT《第 1 章 Python 数据分析基础 III》与 2026-03-23 课堂转录。
1. 本讲/本章知识框架#
| 主线 | 知识点 | 核心内容 | 关系/目的 |
|---|---|---|---|
| 一、数据读写 | Python 内置读写 | open + w/a/r;write、read、readline、readlines;理解文件指针与关闭文件。 | 数据进入/离开分析流程的基础。 |
| Pandas 数据读取 | read_csv/read_table/read_excel/read_json/read_pickle 等;关注 sep、header、names、index_col、na_values、nrows、chunksize、skiprows。 | 把外部数据转为 DataFrame/Series。 | |
| Pandas 数据写出 | to_csv、Series.to_csv;sep、na_rep、index、header、columns 等。 | 保存分析结果或中间数据。 | |
| JSON 处理 | json.loads/json.dumps;pd.read_json/to_json;orient=records。 | 处理 API、Web、嵌套键值数据。 | |
| 二、数据清洗 | 总体目标 | 把数据整理为“正确、干净、可分析”的形式;问题导向,不限于 PPT 中列出的操作。 | 实际项目中清洗常占大量时间。 |
| 去重 | duplicated 判断重复;drop_duplicates 删除重复;subset 指定判断维度;keep 控制保留首/末次出现。 | 问卷、投票、用户记录去重。 | |
| 映射转换 | Series.map 接收字典或函数;常与 str.lower/strip 配合。 | 把原始类别转为可汇总的新维度。 | |
| 替换值 | replace 做定制化替换;fillna 是缺失值替换的特殊情况。 | 异常值、哨兵值、编码值转换。 | |
| 重命名索引 | Index.map、rename(index=…, columns=…);inplace 控制原地修改。 | 统一行列标签、增强可读性。 | |
| 三、数据聚合与分组 | GroupBy 机制 | split-apply-combine:按键分组,对组应用函数,再合并结果。 | 分类汇总、透视表、差异分析。 |
| 分组键来源 | 列名、Series/数组、字典/Series 映射、函数、索引级别 level。 | 分组依据不一定必须在 DataFrame 中。 | |
| 分组对象操作 | GroupBy 是延迟对象;可迭代为 (name, group);可先分组后选列。 | 调试和精细处理每一组。 | |
| 聚合 | mean、sum、count、size、std、quantile、describe、自定义 agg、多列多函数聚合。 | 把每组转为标量/Series/DataFrame 结果。 |
原文件提示: 主线记忆:本章逻辑不是“背函数列表”,而是:读入数据 → 判断数据问题 → 清洗/转换为可分析形态 → 按业务维度分组 → 聚合形成可解释的统计结论。
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| 文件对象 | file object | open 返回的对象,用于读写文件。 | 简单文本读写。 | 打开模式 w/a/r 差异;忘记 close。 | w 与 a 有何区别? |
| 顺序读取 | read | 从文件当前位置读取指定字符数或全部内容。 | 一次性读取小文件。 | 第二次 read 从上次位置继续。 | 为什么 f.read(20) 后再 read() 不是从头读? |
| 按行读取 | readline/readlines | readline 读一行;readlines 返回所有行列表。 | 逐行处理或带行号输出。 | readlines 可能占内存。 | 三种读取方法的区别。 |
| CSV 读取 | read_csv | 读取逗号或指定分隔符文本为 DataFrame。 | 表格型数据最常见入口。 | 默认第一行为列名;路径分隔符。 | 无表头如何读取? |
| 表头参数 | header/names | header=None 表示无标题行;names 指定列名。 | 原始文件无列名或列名需替换。 | names 与 index_col 必须匹配。 | 为什么 index_col=“message” 报错? |
| 索引列 | index_col | 把文件中的某列/多列作为 DataFrame 行索引。 | 主键、层次化索引。 | 多列会形成 MultiIndex。 | 如何读取后让 a,b 两列成为索引? |
| 缺失值标记 | na_values | 把自定义符号识别为 NaN。 | 文件中用 NULL、?、-999 表示缺失。 | 全局列表 vs 分列字典。 | 每列缺失标记不同怎么处理? |
| 分块读取 | chunksize | 按块返回可迭代 TextFileReader。 | 大文件统计。 | 每块结果要累加合并。 | 如何统计大文件 key 频数? |
| JSON | JavaScript Object Notation | 键值对形式的数据交换格式。 | API/Web 数据。 | JSON null 与 Python None;orient 差异。 | loads 与 dumps 区别。 |
| 数据清洗 | data cleaning | 发现并处理重复、缺失、异常、格式不一致等问题。 | 真实数据分析前期。 | 清洗不是固定步骤,而是问题导向。 | 为什么清洗影响后续结论? |
| 重复判断 | duplicated | 返回布尔 Series,标记重复行。 | 识别重复记录。 | 默认按整行判断;第一次出现标 False。 | 为什么只有后出现的重复行是 True? |
| 删除重复 | drop_duplicates | 删除 duplicated 为 True 的行。 | 问卷/IP/手机号去重。 | subset 和 keep 的含义。 | 保留最新记录怎么写? |
| 映射转换 | map | 用函数或字典逐元素转换 Series。 | 类别合并、编码转义。 | 大小写、空格导致匹配失败。 | 如何把 food 映射为 animal? |
| 值替换 | replace | 按规则把某些值替换为另一些值。 | 异常值、哨兵值处理。 | 列表对应替换 vs 字典替换。 | 把 -999 替换为 NaN 怎么写? |
| 轴标签重命名 | rename | 按函数或字典修改行/列标签。 | 规范列名、改行名。 | map 不赋值不改变原对象;inplace。 | rename 和 replace 改的对象有何不同? |
| 分组对象 | GroupBy | 由 groupby 产生的延迟计算对象。 | 后续聚合/转换/迭代。 | 不调用聚合时没有实际统计结果。 | grouped 变量为什么看不到均值? |
| 分割-应用-合并 | split-apply-combine | 先按键分组,再对每组应用函数,最后合并输出。 | groupby 基本机制。 | 聚合后原样本索引通常失去意义。 | 解释 groupby 的基本原理。 |
| 分组样本数 | size | 统计每组行数,包括缺失。 | 订单数、记录数。 | 与 count 不同。 | size 和 count 的区别。 |
| 有效值计数 | count | 统计每组非缺失值数量。 | 有效观测数。 | 遇到 NaN 不计数。 | 为什么 count 小于 size? |
| 聚合 | aggregation/agg | 把数组/组转换为标量或较低维结果。 | 均值、总和、标准差、极差。 | 自定义函数用 agg 传函数名,不加括号。 | 如何计算每组极差? |
| 分位数 | quantile | 按排序位置取值,可插值。 | 查看分布位置。 | 0.9 靠近最大值,不是最大值。 | quantile(0.9) 表示什么? |
| 描述统计 | describe | 一次返回 count/mean/std/min/分位数/max。 | 快速理解分组分布。 | 输出可能形成层次化列索引。 | groupby 后 describe 结果结构? |
3. 重点知识详解#
3.1 数据读写:分析流程的入口与出口#
| 维度 | 内容 |
|---|---|
| 概念定义 | 数据读写包括把外部文件加载到 Python/pandas 中,以及把处理或分析结果导出到文件。PPT 将其分为 Python 内置读写、pandas 读写和 JSON 处理。 |
| 直观理解 | 读数据相当于“把原料搬进工作台”;写数据相当于“把中间结果或结论保存下来”。如果读取参数错了,后续清洗和建模都会建立在错误表格上。 |
| PPT 中对应内容 | PPT 第 4-36 页:open/write/read/readline/readlines;pandas read_* 接口;read_csv 参数分类;to_csv;JSON loads/dumps/read_json/to_json。 |
| 老师课堂强调 | 本次转录主要从数据清洗开始,数据读写的课堂补充材料不足;本复习资料以 PPT 为主。 |
| 典型例子 | 读取逗号分隔文件用 pd.read_csv;无标题行用 header=None;自定义列名用 names;多列索引用 index_col=[…];大文件用 chunksize 分块统计。 |
| 可能考点 | 给一段 read_csv 代码判断输出索引/列名;根据文件特点选择 header、sep、index_col、na_values;写出分块读取计数模板。 |
| 常见错误 | 把路径分隔符写错;把 header=None 与 names 混淆;index_col 中指定了不存在的列;大文件直接一次性读取导致内存压力。 |
3.2 Python 内置文件读写:open 模式与文件指针#
| 维度 | 内容 |
|---|---|
| 概念定义 | open(path, mode) 打开文件,mode 常见为 w 写入覆盖、a 追加、r 读取。write 写入字符串;read/readline/readlines 读取内容。 |
| 直观理解 | 文件对象内部有“当前读取位置”。read(20) 后,位置向后移动;再次 read() 会从当前位置继续,而不是自动回到开头。 |
| PPT 中对应内容 | PPT 第 5-10 页:w 写入、a 追加、read、readlines、readline。 |
| 老师课堂强调 | 材料未充分说明 with open 的写法;本资料在代码模板中补充更稳妥的上下文管理写法。 |
| 典型例子 | f = open(“test_file.txt”, “a”) 后写入会追加到文件尾部;readlines 返回行列表,可以 for line in content 遍历。 |
| 可能考点 | 问 w 与 a 的区别;判断 read/readline/readlines 输出;解释为什么第二次 read() 内容不同。 |
| 常见错误 | 忘记换行符导致写入连在一起;忘记关闭文件;以 w 打开已有文件会覆盖原内容。 |
3.3 pandas 读取:read_csv/read_table 的核心参数#
| 维度 | 内容 |
|---|---|
| 概念定义 | pandas 提供多个读取接口。read_csv 默认逗号分隔,read_table 默认制表符分隔;二者都可通过 sep 指定分隔符,并可处理表头、索引、缺失值、日期、分块等问题。 |
| 直观理解 | 同一个文本文件,关键是让 pandas 正确理解“每行怎么拆列、哪行是列名、哪列是索引、哪些符号是缺失”。 |
| PPT 中对应内容 | PPT 第 11-25 页:read_csv 接口选项,参数类别包括索引、类型推断/转换、日期解析、迭代、不规整数据;sep、header、names、index_col、skiprows、na_values、nrows、chunksize。 |
| 老师课堂强调 | 转录末尾学生练习提到读取 URL、命名列、缺失值统计和 dropna,说明读入后要马上检查数据结构和缺失情况。 |
| 典型例子 | 不固定空格分隔用 sep=r”\s+“;跳过文件说明行用 skiprows=[0,2];每列缺失标记不同用 na_values={“col1”: [”?”], “col2”: [“NULL”]}。 |
| 可能考点 | 根据文件片段写 read_csv 参数;说明 nrows 与 chunksize 区别;解释 sep=r”\s+” 的含义。 |
| 常见错误 | 把正则写成 “\S+“(非空白)而不是 “\s+“(空白);列名数量与数据列数量不一致;未检查读入后的 df.head()/df.info()。 |
3.4 JSON 处理:从键值对象到表格#
| 维度 | 内容 |
|---|---|
| 概念定义 | JSON 是 Web 和 API 中常见的数据交换格式,语法接近 Python 字典/列表。json.loads 把 JSON 字符串转为 Python 对象,json.dumps 把 Python 对象转为 JSON 字符串。pandas 可用 read_json/to_json。 |
| 直观理解 | CSV 像二维表;JSON 更像“嵌套的字典和列表”。当 JSON 每个对象代表一行时,可以较自然地转为 DataFrame。 |
| PPT 中对应内容 | PPT 第 32-36 页:JSON 定义、loads/dumps、字典列表构造 DataFrame、pd.read_json、to_json orient。 |
| 老师课堂强调 | 转录中未充分讲解 JSON,考试若涉及应以 PPT 代码和参数为主。 |
| 典型例子 | pd.DataFrame(records, columns=[…]) 从字典列表抽取部分字段;df.to_json(orient=“records”) 使每一行作为 JSON 数组中的一个对象,行索引会丢失。 |
| 可能考点 | 区分 loads/dumps;说明 read_json 默认假设;解释 orient=“records” 的影响。 |
| 常见错误 | 把 JSON 字符串当 Python 字典直接索引;忽视嵌套结构;不知道 orient 改变输出形态。 |
3.5 数据清洗总体思想:问题导向#
| 维度 | 内容 |
|---|---|
| 概念定义 | 数据清洗是将数据整理为正确、干净、可用于分析的形式,包含缺失值处理、数据转换、过滤、清理、去重、替换、重命名等。 |
| 直观理解 | 清洗不是固定函数清单,而是围绕“我要回答什么问题”判断数据是否足以支持结论。 |
| PPT 中对应内容 | PPT 第 39-40 页:数据清洗两类操作为缺失值处理和数据转换;本节主要讲数据过滤、清理和其他转换方式。 |
| 老师课堂强调 | 老师强调真实项目中前期数据处理常占一半以上时间,包含错误、理解、核查、去重等;清洗目的是让数据支持明确现象、规律和决策。 |
| 典型例子 | 问卷、投票数据要识别重复;健身软件要保留每人最近一次身高体重;异常编码 -999 需先理解含义再替换。 |
| 可能考点 | 解释为什么清洗重要;列举清洗的典型操作;给业务任务判断应做哪些清洗。 |
| 常见错误 | 只机械调用函数,不检查数据含义;没理解异常值就替换;清洗后不验证结果。 |
3.6 去重:duplicated 与 drop_duplicates#
| 维度 | 内容 |
|---|---|
| 概念定义 | duplicated 返回布尔 Series,标记每一行是否为重复行;drop_duplicates 删除重复行。默认按所有列组成的整行判断,第一次出现保留,后续重复标记为 True。 |
| 直观理解 | 重复不是“所有相同记录都删掉”,而是“每组相同记录保留一个”。subset 决定按哪些列判断重复,keep 决定保留哪一次。 |
| PPT 中对应内容 | PPT 第 41-42 页:duplicated、drop_duplicates、subset、keep=“last”。 |
| 老师课堂强调 | 老师举投票/问卷例子:可按手机号、IP、设备等维度去重;又举健身记录例子:按学号保留最后一次记录可用 keep=“last”。强调默认按整行判断。 |
| 典型例子 | data.drop_duplicates([“student_id”], keep=“last”) 保留每名学生最后一次记录。 |
| 可能考点 | 判断 duplicated 输出;写按某列去重代码;说明默认保留第一条和 keep=“last” 的区别。 |
| 常见错误 | 误以为只看第一列;误把先出现记录也标为 True;不知道 keep=“last” 适合保留最新记录。 |
3.7 map 映射转换:字典映射与函数映射#
| 维度 | 内容 |
|---|---|
| 概念定义 | Series.map 可接收字典或函数,把 Series 中每个元素映射成新值,并返回同索引的新 Series。 |
| 直观理解 | map 适合把“原始类别名”转换成“可汇总类别”。比如把 bacon、pulled pork 等映射为 pig,把 beef 相关食物映射为 cow。 |
| PPT 中对应内容 | PPT 第 43-46 页:肉类数据、meat_to_animal 映射、大小写统一、字典/函数两种 map 用法。 |
| 老师课堂强调 | 老师强调 Python 对大小写敏感,映射前最好 lower;也可写 lambda x: meat_to_animal[x.lower()]。如果数据本身是字典,直接传字典更简洁。 |
| 典型例子 | data[“animal”] = data[“food”].str.lower().map(meat_to_animal)。之后可按 animal groupby 汇总 ounces。 |
| 可能考点 | 写出添加 animal 列代码;比较 map(dict) 与 map(lambda);说明为什么要 lower/strip。 |
| 常见错误 | 键值大小写不一致导致 NaN;映射字典缺少某些类别;把 DataFrame.map 与 Series.map 混用。 |
3.8 replace 值替换:异常/哨兵值处理#
| 维度 | 内容 |
|---|---|
| 概念定义 | replace 用于把指定值替换成其他值,可传单值、列表、两个列表、字典;fillna 是缺失值填充的特殊情形。 |
| 直观理解 | 现实数据常用 -999、-1000、负数等表示异常或缺失。replace 的难点不在代码,而在先判断这些值代表什么。 |
| PPT 中对应内容 | PPT 第 47-48 页:replace、inplace=True、列表/字典多值替换。 |
| 老师课堂强调 | 老师强调参数来自对数据的观察:describe、head、tail、分类值统计等能帮助发现异常。字典替换更清楚地表达“谁替换成谁”。 |
| 典型例子 | data.replace([-999, -1000], np.nan) 统一替换;data.replace({-999: np.nan, -1000: 0}) 定制替换。 |
| 可能考点 | 写出把多个哨兵值替为 NaN 的代码;比较列表对应替换与字典替换;解释 inplace。 |
| 常见错误 | 不知道异常值业务含义就替换;两个列表长度不一致;把 replace 当作改列名的方法。 |
3.9 索引和列名重命名:Index.map 与 rename#
| 维度 | 内容 |
|---|---|
| 概念定义 | 轴标签也能像 Series 值一样通过函数或映射转换。Index.map 可生成转换后的索引;rename 可用函数或字典修改 index/columns,支持 inplace。 |
| 直观理解 | 改名不是改数据值,而是改“行列标签”。标签统一后,筛选、分组、展示更可靠。 |
| PPT 中对应内容 | PPT 第 49-50 页:索引 map、赋值原地修改、rename、index/columns 字典、inplace。 |
| 老师课堂强调 | 老师强调字符串空格会导致代码认为是不同标签,如 “NEW” 与 “NEW ” 完全不同;必要时 strip。传函数时不加括号表示把函数本身作为参数。 |
| 典型例子 | data.rename(index=str.title, columns=str.upper);data.rename(index={“OHIO”:“INDIANA”}, columns={“three”:“peekaboo”})。 |
| 可能考点 | 判断 rename 后是否改变原对象;写同时改行列名代码;解释函数名不加括号。 |
| 常见错误 | 未赋值也未 inplace 导致原对象没变;误把 str.upper() 写成调用结果;忽视空格和大小写。 |
3.10 GroupBy 机制:延迟计算与结果索引#
| 维度 | 内容 |
|---|---|
| 概念定义 | groupby 根据一个或多个键把对象分成若干组,得到 GroupBy 对象;该对象保存分组关系但尚未计算。调用 mean/sum/agg 等后才产生结果。 |
| 直观理解 | 核心是 split-apply-combine:分开、分别计算、合并。聚合结果的索引通常是分组键的唯一值,而不是原来的行索引。 |
| PPT 中对应内容 | PPT 第 54-58 页:groupby 功能、GroupBy 机制图、按 key1 求 data1 平均、多个数组生成层次化索引。 |
| 老师课堂强调 | 老师强调 grouped 类似生成器/迭代对象,没做聚合前不含均值结果;用 K1 分组后结果索引就是 K1 的唯一值;聚合会损失部分原始行列信息。 |
| 典型例子 | df[“data1”].groupby(df[“key1”]).mean() 返回按 key1 唯一值索引的 Series。 |
| 可能考点 | 解释 GroupBy 为什么还没有计算;判断多键分组结果索引;说明聚合后原样本索引为什么消失。 |
| 常见错误 | 把 GroupBy 对象误认为结果表;连续变量取值太多时盲目分组;忽视多键分组产生 MultiIndex。 |
3.11 分组键来源:列名、外部数组、字典/Series、函数、索引级别#
| 维度 | 内容 |
|---|---|
| 概念定义 | groupby 的 by 可以是 DataFrame 列名、长度匹配的 Series/数组、字典或 Series 映射、函数,或通过 level 指定 MultiIndex 的某一级。 |
| 直观理解 | 分组依据不一定必须是 DataFrame 的列;只要能与待分组对象的轴对应,就可作为分组依据。 |
| PPT 中对应内容 | PPT 第 59-69 页:外部数组分组、列名分组、字典/Series 分组、函数分组、level 分组、分组方法总结。 |
| 老师课堂强调 | 老师强调外部 states/years 也可作为分组依据;函数作为分组键会作用在索引值上;值和索引可通过 set_index/reset_index 转换,逻辑上无本质差别。 |
| 典型例子 | people.groupby(len).sum() 按行索引字符串长度分组;people.groupby(mapping, axis=1).sum() 按列映射分组;df.groupby(level=“cty”, axis=1).count() 按列索引级别分组。 |
| 可能考点 | 给数据判断 groupby 作用在哪个轴;写按索引长度分组代码;说明 level 与 axis 的含义。 |
| 常见错误 | 外部数组长度不匹配;axis=0/1 混淆;字典中多余键不影响,但缺少键会导致对应项无法分到目标组。 |
3.12 分组迭代与分组后选列#
| 维度 | 内容 |
|---|---|
| 概念定义 | GroupBy 支持 for name, group in grouped 迭代;每次得到组名和该组数据块。对 DataFrameGroupBy 可用 [“col”] 或 [[“col1”,“col2”]] 选择子列再聚合。 |
| 直观理解 | 迭代用于看清每组数据或对不同组执行不同逻辑;选列用于减少计算量并使输出更聚焦。 |
| PPT 中对应内容 | PPT 第 61-63 页:GroupBy 迭代、转字典、分组后选取一列/列子集。 |
| 老师课堂强调 | 老师强调单键分组 name 是一个值,多键分组 name 可能是元组;即使某组只有一行,group 仍保持 DataFrame 形态;先选列后分组或先分组后选列都可。 |
| 典型例子 | pieces = dict(list(df.groupby(“key1”))) 后 pieces[“b”] 取 B 组;df.groupby(“key1”)[[“data1”,“data2”]].mean()。 |
| 可能考点 | 写迭代打印每组代码;判断 name 类型;比较 df[“data1”].groupby(df[“key1”]) 与 df.groupby(“key1”)[“data1”]。 |
| 常见错误 | 多列选择少写一层方括号;迭代时把多键 name 当单值;认为每组只有一行就会变 Series。 |
3.13 聚合与 agg:内置函数、自定义函数、多列多函数#
| 维度 | 内容 |
|---|---|
| 概念定义 | 聚合是从数组/组产生标量值或低维统计结果的过程。GroupBy 可直接调用 mean/sum/count/std/quantile/describe,也可用 agg 接收函数名、函数列表、命名元组、列到函数的字典。 |
| 直观理解 | 聚合的价值在于把每组大量明细变成可比较的统计摘要,例如均值、标准差、极差、最大值、总和。 |
| PPT 中对应内容 | PPT 第 70-78 页:常用优化聚合函数、自定义聚合、quantile、describe、tips 数据多列聚合。 |
| 老师课堂强调 | 老师强调自定义函数必须通过 .agg(function) 传入函数名且不加括号;内置聚合可用字符串;多列多函数会生成层次化列索引;命名元组可提升可读性。 |
| 典型例子 | def peak_to_peak(arr): return arr.max()-arr.min(); grouped.agg(peak_to_peak)。tips 按 day 和 smoker 分组后计算 tip_pct 的 mean/std/极差。 |
| 可能考点 | 写自定义极差聚合;判断 mean/std/自定义函数传参方式;解释 describe 输出的层次化列索引;用字典指定不同列不同聚合。 |
| 常见错误 | 写 peak_to_peak() 导致立即调用;把 size 和 count 混淆;不理解多层列索引;聚合后还试图使用原始行索引解释样本。 |
4. Python 实现与代码模板#
原文件提示: 说明:以下模板以 PPT/课堂知识点为依据整理;其中使用 with open、df.info()、errors 等更稳妥写法属于“根据课程内容整理的通用模板”,用于考试与作业可直接改参数套用。
4.1 Python 内置文件读写模板#
# 根据课程内容整理的通用模板:写入/追加文本文件# 输入:path 文件路径;lines 字符串列表# 输出:在磁盘生成或追加文本文件path = "test_file.txt"lines = [f"hello myfile, this is line {i}!\n" for i in range(5)]
# 'w':覆盖写入;如果文件已存在,原内容会被清空with open(path, "w", encoding="utf-8") as f: f.writelines(lines)
# 'a':追加写入;内容写到文件末尾with open(path, "a", encoding="utf-8") as f: for i in range(3): f.write(f"Hello again, this is additional line {i}!\n")
# 常见易错:忘记 \n 会导致多行连在一起;用 'w' 打开旧文件会覆盖原内容。# 根据课程内容整理的通用模板:读取文本文件path = "test_file.txt"
with open(path, "r", encoding="utf-8") as f: first_20 = f.read(20) # 从当前位置读 20 个字符 rest = f.read() # 从当前位置继续读到文件末尾
with open(path, "r", encoding="utf-8") as f: first_line = f.readline() # 每次读一行 second_line = f.readline()
with open(path, "r", encoding="utf-8") as f: all_lines = f.readlines() # 返回每行组成的列表;大文件慎用
# 常见易错:read/readline/readlines 都会移动文件指针;第二次 read 不会自动回到开头。4.2 pandas 读取 CSV/表格数据模板#
import pandas as pd
# 常规读取:默认 sep=',',默认第一行为列名,默认 RangeIndex 为行索引df = pd.read_csv("data.csv")
# 无表头文件:声明 header=None,并用 names 指定列名df = pd.read_csv( "data_no_header.csv", header=None, names=["a", "b", "c", "message"])
# 指定某列为行索引;若 message 不在 names 或原文件列中,会报错df = pd.read_csv( "data.csv", index_col="message")
# 多列层次化索引df = pd.read_csv( "data.csv", index_col=["key1", "key2"])
# 不规则空白分隔:使用正则表达式 sep=r'\s+'df = pd.read_table("space_delimited.txt", sep=r"\s+", engine="python")
# 跳过说明行/注释行# skiprows 可以是行号列表,也可以是整数数据 = pd.read_csv("data_with_notes.csv", skiprows=[0, 2, 3])# 自定义缺失值标记import numpy as npimport pandas as pd
# 所有列共用缺失值标记df = pd.read_csv("data.csv", na_values=["NULL", "NA", "?", "-"])
# 每列缺失标记不同:字典的键是列名,值是该列的缺失值标记列表df = pd.read_csv( "data.csv", na_values={ "score": ["-999", "缺考"], "name": ["", "未知"] })
# 只读前 n 行,适合快速查看文件结构df_head = pd.read_csv("large.csv", nrows=100)
# 常见检查步骤print(df_head.head())print(df_head.info())print(df_head.isna().sum())4.3 大文件分块读取与累计统计模板#
# 根据课程内容整理的通用模板:用 chunksize 分块统计 key 频数import pandas as pd
reader = pd.read_csv("large.csv", chunksize=10000)result = pd.Series(dtype="int64")
for chunk in reader: # 每块内统计 key 的取值个数 counts = chunk["key"].value_counts() # 与累计结果相加;fill_value=0 避免新旧索引不一致产生 NaN result = result.add(counts, fill_value=0)
result = result.sort_values(ascending=False).astype("int64")print(result.head())
# 输入:大文件 large.csv,必须含 key 列# 输出:每个 key 在全文件中的出现次数# 易错点:每个 chunk 的 value_counts 索引可能不同,不能直接用 +,应使用 add(fill_value=0)。4.4 写出 CSV 与 JSON 模板#
import sysimport pandas as pd
# DataFrame 写出 CSVdf.to_csv("output.csv") # 默认写出行索引和列名df.to_csv("output.tsv", sep="\t") # 指定分隔符df.to_csv("output.csv", na_rep="NULL") # 指定缺失值显示方式df.to_csv("output.csv", index=False) # 不保留行索引df.to_csv("output.csv", columns=["a", "b"]) # 按顺序保留部分列
# 写到控制台:PPT 中提到 sys.stdout 表示打印到控制台df.to_csv(sys.stdout, sep="|")
# Series 也可写出s.to_csv("series.csv", header=False)# JSON 读取与写出import jsonimport pandas as pd
json_str = '[{"name": "Alice", "score": 90}, {"name": "Bob", "score": null}]'records = json.loads(json_str) # JSON 字符串 -> Python 对象(列表/字典)json_back = json.dumps(records, ensure_ascii=False) # Python 对象 -> JSON 字符串
df = pd.DataFrame(records, columns=["name", "score"])
# pandas 直接读取特定 JSON 格式# 默认常假设 JSON 数组中每个对象是一行df2 = pd.read_json("records.json")
# 默认 orient 可能按列输出;records 表示每行一个对象,行索引信息会丢失json_records = df.to_json(orient="records", force_ascii=False)4.5 数据清洗模板:去重、映射、替换、重命名#
import numpy as npimport pandas as pd
# 1. 去重# 默认:按整行判断重复,保留第一次出现mask = df.duplicated()df_no_dup = df.drop_duplicates()
# 按部分列判断重复:如手机号/学号/IP# keep='last':保留最后一次记录,适合保留“最新记录”df_latest = df.drop_duplicates(subset=["student_id"], keep="last")
# 2. 映射转换:食物 -> 来源动物meat_to_animal = { "bacon": "pig", "pulled pork": "pig", "pastrami": "cow", "corned beef": "cow", "honey ham": "pig", "nova lox": "salmon"}# 大小写、空格统一后映射,减少意外 NaNdf["animal"] = df["food"].str.lower().str.strip().map(meat_to_animal)
# 也可以用函数/lambda;注意函数名传入 map,不是提前整体调用df["animal2"] = df["food"].map(lambda x: meat_to_animal[x.lower().strip()])
# 3. 替换异常/哨兵值s = pd.Series([1, -999, 2, -1000, 3])s1 = s.replace(-999, np.nan)s2 = s.replace([-999, -1000], np.nan)s3 = s.replace({-999: np.nan, -1000: 0})
# 4. 重命名索引/列名# 生成新对象,不改变原 dfdf2 = df.rename(index=str.title, columns=str.upper)# 部分改名数据 = df.rename(columns={"old_col": "new_col"})# 原地修改(考试题中常问 inplace 是否改变原对象)df.rename(columns={"old_col": "new_col"}, inplace=True)4.6 groupby 分组与聚合模板#
import numpy as npimport pandas as pd
# 给定 DataFrame:df 含 key1, key2, data1, data2
# 1. 单键分组:按 key1 计算 data1 平均值result = df["data1"].groupby(df["key1"]).mean()# 等价语法糖:先分组,再选列result = df.groupby("key1")["data1"].mean()
# 2. 多键分组:结果通常是层次化索引 MultiIndexresult2 = df.groupby(["key1", "key2"])["data1"].mean()# 如需二维表形式,可 unstackwide = result2.unstack()
# 3. 每组样本数 vs 非缺失值计数group_size = df.groupby(["key1", "key2"]).size() # 每组行数,包括缺失group_count = df.groupby(["key1", "key2"]).count() # 每列非缺失个数
# 4. GroupBy 迭代:查看每一组数据for name, group in df.groupby("key1"): print("group name:", name) print(group.head())
# 多键分组时,name 是元组,例如 ('A', 1)for name, group in df.groupby(["key1", "key2"]): print(name, group.shape)
# 5. 转为字典:数据不大时便于按组访问pieces = dict(list(df.groupby("key1")))# pieces["A"] 取 A 组对应的数据块# 6. 字典/Series/函数/索引级别分组
# 字典按列分组:mapping 的键对应列名,值是组名mapping = {"a": "red", "b": "red", "c": "blue", "d": "blue", "e": "red"}col_sum = people.groupby(mapping, axis=1).sum()
# Series 也可作为固定大小映射map_series = pd.Series(mapping)col_count = people.groupby(map_series, axis=1).count()
# 函数分组:函数会作用在索引值上;例如按行索引字符串长度分组by_len = people.groupby(len).sum()
# 层次化索引按级别分组:level 可传级别名或编号;axis=1 表示按列索引分组level_count = data.groupby(level="cty", axis=1).count()# 7. 自定义聚合与多列多函数聚合
def peak_to_peak(arr): """极差:最大值 - 最小值。输入是每一组中的一列 Series。""" return arr.max() - arr.min()
# 自定义函数必须通过 agg/aggregate 传函数名,不加括号g = df.groupby("key1")range_result = g.agg(peak_to_peak)
# 直接调用内置方法desc = g.describe()q90 = g["data1"].quantile(0.9)
# 对一列应用多个函数:内置函数可用字符串,自定义函数传函数对象summary = df.groupby(["day", "smoker"])["tip_pct"].agg(["mean", "std", peak_to_peak])
# 指定输出列名:列表中放 (输出名, 函数) 元组summary_named = df.groupby(["day", "smoker"])["tip_pct"].agg([ ("平均小费率", "mean"), ("小费率标准差", np.std), ("小费率极差", peak_to_peak)])
# 不同列应用不同聚合规则:字典映射列名 -> 函数或函数列表multi_summary = df.groupby(["day", "smoker"]).agg({ "tip_pct": ["mean", "max", "min", "std"], "size": "sum", "tip": np.max})5. 图表/方法选择指南#
| 遇到的数据/任务 | 优先方法 | 答题步骤 | 注意事项 |
|---|---|---|---|
| 普通逗号分隔表格文件 | pd.read_csv | sep 默认逗号;检查 head/info。 | 适合规范二维表。 |
| 制表符或其他固定分隔符 | pd.read_table 或 read_csv(sep=…) | sep=” “、sep=”|” 等。 | read_csv/read_table 本质都能指定 sep。 |
| 空格数量不固定 | 正则分隔 sep=r”\s+“ | 表示一个或多个空白字符。 | 别写成 \S+;那是非空白。 |
| 无标题行 | header=None + names=[…] | 先声明无表头,再手动命名。 | 列名数量要与数据列匹配。 |
| 某列/多列是主键或层级 | index_col=“col” / index_col=[…] | 读取时建立索引。 | 也可读入后 set_index。 |
| 自定义缺失值符号 | na_values | 全局列表或分列字典。 | 读入时统一为 NaN,后续便于处理。 |
| 大文件只想预览 | nrows | 读取前 n 行。 | 不是分块,不适合全量统计。 |
| 大文件要全量统计 | chunksize + 迭代累加 | 每块 value_counts,再 add(fill_value=0)。 | 避免一次性读入内存。 |
| Web/API 数据 | json.loads / pd.read_json | 先确认 JSON 结构。 | 嵌套 JSON 可能需 normalize,材料未充分展开。 |
| 重复问卷/IP/手机号 | duplicated/drop_duplicates(subset=…) | subset 设定判断维度。 | 默认按整行,不一定符合业务。 |
| 保留每人最新记录 | drop_duplicates(subset=key, keep=“last”) | 先确保数据按时间排序。 | 如果时间未排序,keep=“last” 不等于最新。 |
| 类别名不适合分析 | Series.map(dict/function) | 先 lower/strip 统一格式。 | 映射缺失会产生 NaN。 |
| 哨兵值/异常编码 | replace 或 read_csv(na_values=…) | 先通过 describe/head/频数理解含义。 | 不要未验证就替换。 |
| 行列标签不规范 | rename / Index.map | 统一大小写、去空格、改可读名称。 | rename 改标签,不改值。 |
| 按类别汇总均值/总和 | groupby(…).mean/sum | 离散变量更适合分组。 | 连续变量取值太多时不宜直接分组。 |
| 每组记录数 | groupby(…).size() | 统计行数。 | 包含缺失;与 count 不同。 |
| 每组有效值数 | groupby(…).count() | 按列统计非缺失单元格。 | count 结果可能多列。 |
| 想查看每组明细 | for name, group in df.groupby(…) | 迭代打印或定制处理。 | 多键 name 为元组。 |
| 按外部分类表分组 | groupby(dict/Series/array) | 分组依据可不在原 DataFrame。 | 长度或索引要能对应。 |
| 按 MultiIndex 某层汇总 | groupby(level=…, axis=…) | level 指级别;axis 指行/列方向。 | axis=1 表示列方向。 |
| 一列多个统计量 | agg([“mean”, “std”, func]) | 可混合字符串和函数对象。 | 自定义函数不加括号。 |
| 不同列不同统计量 | agg({“col1”: […], “col2”: func}) | 字典表达列到函数的映射。 | 输出常为层次化列索引。 |
原文件提示: 分析题答题步骤:先说明数据问题或分析目标;再说明选择的函数和关键参数;随后说明输出结构(Series/DataFrame、索引/列索引);最后说明如何解释结果。
6. 公式与指标总结#
| 公式/指标 | 表达式 | 符号含义 | 适用条件 | 计算步骤 | 考试易错点 |
|---|---|---|---|---|---|
| GroupBy 机制 | split → apply → combine | split:按键划分数据;apply:每组计算;combine:合并结果。 | 适用于分类汇总。 | 按分组键确定唯一组;对每组调用函数;拼接各组结果。 | 聚合后原始行索引通常失去意义;结果索引来自分组键。 |
| 均值 | x̄ = (Σxᵢ) / n | x_i 为组内数值;n 为有效样本数。 | 描述每组集中趋势。 | groupby(…).mean()。 | 非数值列一般不参与均值;缺失值通常被跳过。 |
| 总和 | S = Σxᵢ | x_i 为组内数值。 | 销售额、数量等可加指标。 | groupby(…).sum()。 | 不要对无意义编码求和。 |
| 样本数 | size = 每组行数 | 不区分是否有缺失。 | 订单数、记录数。 | groupby(…).size()。 | 与 count 不同,size 包含 NaN 所在行。 |
| 有效值计数 | count = 非缺失值个数 | 按列统计非 NaN 单元格。 | 评估每列有效观测。 | groupby(…).count()。 | 不同列 count 可不同。 |
| 标准差 | s = sqrt(Σ(xᵢ - x̄)² / (n - 1)) | 衡量组内离散程度。 | 比较波动差异。 | groupby(…).std()。 | 样本过少时 std 可能为 NaN。 |
| 极差 | range = max(x) - min(x) | 组内最大值减最小值。 | 快速衡量跨度。 | 自定义函数 peak_to_peak 后 agg。 | 受异常值影响大。 |
| 分位数 | q_p = 排序后 p 位置的值 | p∈[0,1];quantile(0.9) 接近高端位置。 | 描述分布位置。 | groupby(…).quantile(0.9)。 | 0.9 不是最大值;pandas 可能插值。 |
| 小费比例 | tip_pct = tip / total_bill | tip 为小费金额;total_bill 为总账单。 | tips 数据的衍生指标。 | df[“tip_pct”] = df[“tip”] / df[“total_bill”]。 | 分母为 0 时要处理;材料中未出现分母为 0。 |
| 缺失值比例 | missing_rate = isna().sum()/len(df) | 缺失个数除以总行数。 | 清洗前评估质量。 | df.isna().mean()。 | PPT未列公式;属于补充理解。 |
7. 课堂重点与考试提示#
7.1 必背概念#
- 数据清洗的目标:不是机械处理,而是把数据整理成能支持分析结论和决策的正确、干净形式。
- duplicated/drop_duplicates 默认按整行判断重复;第一次出现保留,后续重复才标记为 True。
- map 可接收字典或函数;Python 对大小写和空格敏感,映射前常做 lower/strip。
- replace 用于定制化替换;参数来自对数据分布和业务含义的理解。
- GroupBy 是延迟对象:只保存分组关系;调用 mean/sum/agg 后才得到统计结果。
- groupby 的 by 非常灵活:列名、外部数组、Series、字典、函数、索引级别均可。
- 聚合后结果索引来自分组键;原始样本行索引通常不再有解释意义。
- size 与 count 不同:size 统计行数,count 统计非缺失值数。
7.2 必会代码#
- pd.read_csv(…, sep=…, header=None, names=…, index_col=…, na_values=…, chunksize=…)。
- df.duplicated()、df.drop_duplicates(subset=[…], keep=“last”)。
- df[“new”] = df[“col”].str.lower().str.strip().map(mapping)。
- s.replace({-999: np.nan, -1000: 0})。
- df.rename(index=…, columns=…, inplace=…)。
- df.groupby([“key1”,“key2”])[“value”].mean()。
- for name, group in df.groupby(…): …。
- grouped.agg([“mean”, “std”, custom_func]) 与 grouped.agg({“col1”: […], “col2”: “sum”})。
7.3 必会分析思路#
- 拿到数据先检查:head/info/describe/isna/value_counts,确认列名、类型、缺失、异常、重复。
- 根据问题选择清洗维度:比如问“不同用户”就按用户 ID 去重;问“最新状态”先按时间排序再 keep=“last”。
- 分组前明确分组键:键是否离散、取值是否过多、是否存在大小写/空格导致的伪类别。
- 聚合后解释结构:结果是 Series 还是 DataFrame,行索引/列索引分别代表什么。
- 分析差异不能只看均值;必要时同时看 count/std/极差/分位数/describe。
7.4 高频易错点#
- 把语音转录中的“group back/google map”误解为别的函数:应为 groupby。
- read_csv 无表头时忘记 header=None,导致第一行数据被当作列名。
- map 前未统一大小写,字典匹配失败,结果出现 NaN。
- 用 replace 处理异常值前没有确认异常值含义。
- 以为 groupby 后已经计算;实际上要继续调用聚合/转换。
- 把 count 当成每组行数;含缺失时应区分 size。
- 自定义聚合函数写成 peak_to_peak() 而不是 peak_to_peak。
- axis=1 和 axis=0 混淆,按列分组时要明确 axis=1。
7.5 可能出题方式#
- 给文件片段,让你写 read_csv 参数并说明读入后的索引/列名。
- 给含重复记录 DataFrame,让你写去重代码并判断保留哪几行。
- 给映射字典和大小写混杂数据,让你补全 map 代码。
- 给异常值编码规则,让你用 replace 一行完成替换。
- 给 groupby 代码,让你判断结果的索引、列索引和数值含义。
- 给分组统计任务,让你选择 size/count/mean/std/agg。
- 给多列聚合需求,让你写 agg 字典或命名聚合代码。
8. 期末复习版精简笔记#
数据读写#
- open 模式:w 覆盖写,a 追加写,r 读;read/readline/readlines 都移动文件指针。
- read_csv 重点参数:sep、header、names、index_col、skiprows、na_values、nrows、chunksize。
- 无标题行:header=None;手动列名:names=[…];多列索引:index_col=[…];正则空白:sep=r”\s+”。
- 分块读取:for chunk in pd.read_csv(…, chunksize=N),每块统计后 add(fill_value=0) 累加。
- JSON:loads 字符串→Python;dumps Python→字符串;to_json(orient=“records”) 每行一个对象。
数据清洗#
- 清洗目标:让数据正确、干净、可支持分析结论;真实项目中清洗通常非常耗时。
- 去重:duplicated 判断,drop_duplicates 删除;默认按整行;subset 指定列;keep=“last” 保留最后一次。
- 映射:Series.map(dict/function),映射前常 lower/strip;映射失败会产生 NaN。
- 替换:replace 单值/列表/字典;fillna 是缺失填充;参数来自数据理解。
- 重命名:Index.map 或 rename(index=…, columns=…);不赋值且无 inplace 不改变原对象。
聚合与分组#
- groupby = split-apply-combine;GroupBy 对象只是分组关系,聚合后才计算。
- 分组键可来自列名、外部数组、Series、字典、函数、MultiIndex level。
- 多键分组结果常是 MultiIndex;可 unstack 转二维表。
- 迭代:for name, group in df.groupby(…):;多键 name 是元组。
- size 行数,count 非缺失值数;自定义聚合用 grouped.agg(func),func 不加括号。
- 多列多函数聚合:agg([“mean”, “std”, func]) 或 agg({“col1”: […], “col2”: “sum”})。
9. 自测题与参考答案
原文件提示: 使用方式:建议先遮住答案完成,再对照解析。题目尽量贴合 PPT 和课堂讲法,不覆盖材料之外的复杂 API。
9.1 选择题#
1. 关于 open(“file.txt”, “w”),下列说法正确的是( )。#
A. 在文件末尾追加内容#
B. 文件不存在时一定报错#
C. 若文件已存在会覆盖原内容#
D. 只能读取文件#
答案:C。解析:w 是 write 模式,写入时会覆盖已有文件;追加应使用 a。
2. 读取无标题行 CSV 且手动指定列名,应使用( )。#
A. header=None, names=[…]#
B. index_col=None, names=False#
C. sep=None, header=True#
D. chunksize=None#
答案:A。解析:header=None 声明文件没有列名,names 指定新列名。
3. duplicated 默认判断重复的依据是( )。#
A. 第一列#
B. 最后一列#
C. 所有列组成的整行#
D. 行索引#
答案:C。解析:默认按整行比较,只有所有列都相同才视为重复。
4. 若要按 student_id 去重并保留最后一次记录,应写( )。#
A. df.drop_duplicates(“student_id”, keep=“first”)#
B. df.drop_duplicates(subset=[“student_id”], keep=“last”)#
C. df.duplicated(subset=[“student_id”], keep=“all”)#
D. df.replace(“student_id”)#
答案:B。解析:subset 指定按哪列判断;keep=“last” 保留最后出现。
5. Series.map(mapping) 中 mapping 是字典时,字典的键通常对应( )。#
A. Series 的索引#
B. Series 的原始取值#
C. DataFrame 的列数#
D. 分组后的均值#
答案:B。解析:map 会把每个元素作为键查找字典中的值。
6. 关于 GroupBy 对象,下列说法正确的是( )。#
A. 一创建就已经计算出均值#
B. 只能按 DataFrame 中已有列分组#
C. 可迭代得到组名和数据块#
D. 不能使用自定义函数#
答案:C。解析:GroupBy 是延迟对象,支持迭代;分组键来源非常灵活,也可用 agg 自定义函数。
7. groupby(…).size() 与 groupby(…).count() 的区别是( )。#
A. size 统计行数,count 统计非缺失值#
B. size 统计非缺失值,count 统计行数#
C. 二者完全相同#
D. count 只能用于字符串#
答案:A。解析:含缺失时二者可能不同。
8. 自定义极差函数 def p2p(x): return x.max()-x.min(),正确聚合方式是( )。#
A. grouped.p2p()#
B. grouped.agg(p2p)#
C. grouped.agg(p2p())#
D. grouped.map(p2p)#
答案:B。解析:自定义聚合通过 agg 传函数对象,不能先加括号调用。
9.2 判断题#
1. read()、readline()、readlines() 都会改变文件对象当前读取位置。#
答案:对。解析:读取后文件指针会后移。
2. pd.read_csv 默认会把第一行作为列名。#
答案:对。解析:默认 header=0。
3. drop_duplicates 默认会删除所有重复记录,包括第一次出现的记录。#
答案:错。解析:默认保留第一次出现,删除后续重复。
4. map 进行字典映射时,“Bacon” 与 “bacon” 会被视为同一个键。#
答案:错。解析:Python 字符串大小写敏感,应先 lower。
5. rename 默认会生成新对象,不一定原地修改。#
答案:对。解析:若要原地修改需赋值或 inplace=True。
6. groupby([“key1”, “key2”]) 的结果通常具有层次化索引。#
答案:对。解析:多个分组键产生 MultiIndex。
7. 函数作为 groupby 分组键时,会作用在索引值上。#
答案:对。解析:如 people.groupby(len) 按索引字符串长度分组。
8. quantile(0.9) 一定等于最大值。#
答案:错。解析:0.9 分位靠近高端但不是必然最大值,可能插值。
9.3 简答题#
1. 用标准答题表述解释数据清洗的目的。#
标准答案:数据清洗的目的是发现并处理数据中的重复、缺失、异常、格式不一致等问题,将原始数据整理成正确、干净、能够支持后续统计分析和决策结论的形式。清洗应从分析问题出发,而不是机械套用固定步骤。
2. 说明 duplicated 与 drop_duplicates 的关系。#
标准答案:duplicated 返回布尔 Series,用于标识哪些行被视为重复;drop_duplicates 则根据相同判断逻辑删除重复行并返回去重后的对象。二者默认按整行判断,保留第一次出现的值组合,可通过 subset 和 keep 调整。
3. 为什么老师强调 map 前要处理大小写和空格?#
标准答案:因为 Python 字符串匹配严格区分大小写和空格。字典映射时,“bacon”、“Bacon”、“bacon ” 都是不同键,若不统一格式可能匹配失败并产生 NaN,影响后续分组统计。
4. 解释 GroupBy 的 split-apply-combine。#
标准答案:split 是根据分组键把原始数据拆成若干组;apply 是对每一组应用统计或自定义函数;combine 是把各组结果按分组键合并为 Series 或 DataFrame。
5. size 与 count 在缺失值场景下有什么区别?#
标准答案:size 统计每组的行数,不管行中是否有缺失值;count 对每列分别统计非缺失值数量,因此有 NaN 时 count 可能小于 size,不同列的 count 也可能不同。
6. 为什么聚合后原始样本索引通常不再重要?#
标准答案:聚合结果代表每个组的统计值,而不是某一条原始记录。即使某组只有一条记录,从逻辑上它仍是“该组聚合结果”,结果索引应解释为分组标签而非原样本标签。
9.4 代码阅读题#
1. 阅读代码,判断输出 mask 中哪一类行会被标记为 True。#
data = pd.DataFrame({"k1": ["one", "two", "one", "two", "one", "two", "two"], "k2": [1, 1, 2, 3, 3, 4, 4]})mask = data.duplicated()答案与解析:只有与前面已出现整行完全相同的后续记录会标记为 True。本例中最后两行 k1=“two”, k2=4 重复,第一次出现为 False,后一次为 True。
2. 阅读代码,说明 result 的索引是什么。#
result = df["data1"].groupby([df["key1"], df["key2"]]).mean()答案与解析:result 通常是一个 Series,其索引为由 key1 和 key2 唯一组合构成的 MultiIndex。每个索引位置对应该组合下 data1 的均值。
3. 阅读代码,指出 potential bug。#
meat_to_animal = {"bacon": "pig", "pulled pork": "pig"}data["animal"] = data["food"].map(meat_to_animal)答案与解析:如果 food 中有 “Bacon”、” bacon” 等大小写或空格不一致的值,会映射失败产生 NaN。应先 data[“food”].str.lower().str.strip() 再 map。
4. 阅读代码,解释为什么 grouped 不是均值结果。#
grouped = df["data1"].groupby(df["key1"])print(grouped)答案与解析:grouped 是 GroupBy 对象,保存分组关系但尚未计算。要得到均值需调用 grouped.mean()。
9.5 代码补全题#
1. 读取无表头 CSV,列名为 a,b,c,message,并把 message 作为索引。#
df = pd.read_csv("data.csv", ________, names=["a", "b", "c", "message"], index_col=________)答案:header=None;“message”。解析:无表头必须显式声明,否则第一行数据会被误读为列名。
2. 把 -999 和 -1000 都替换为 np.nan。#
s_clean = s.replace(________, ________)答案:[-999, -1000];np.nan。解析:列表中的所有原值统一替换为后面的值。
3. 按 key1、key2 分组,计算 value 的均值。#
ans = df.groupby(________)[________].mean()答案:[“key1”, “key2”];“value”。解析:多个列名组成列表作为分组键,选取 value 列后求均值。
4. 自定义极差函数并用于分组聚合。#
def peak_to_peak(arr): return ________
ans = grouped.agg(________)答案:arr.max() - arr.min();peak_to_peak。解析:agg 接收函数对象,不能写 peak_to_peak()。
9.6 数据分析应用题#
1. 你获得一份线上投票数据,包含 user_id、ip、device、candidate、time。老师课堂提到这种场景可能需要去重。请给出分析步骤。#
参考答案:步骤:①先检查数据量、缺失、重复;②明确去重口径,如按 user_id、ip 或 device 去重,口径应由业务规则决定;③若保留最新投票,先按 time 排序,再 drop_duplicates(subset=[口径列], keep=“last”);④统计去重前后记录数变化;⑤再按 candidate groupby 统计票数。
2. 你有销售明细数据,包含 region、product、sales、date。要比较不同地区不同产品的销售差异,应如何做?#
参考答案:步骤:①检查 sales 是否有缺失/异常;②用 df.groupby([“region”,“product”])[“sales”].agg([“count”,“sum”,“mean”,“std”]);③如果要形成矩阵,可对 sum 或 mean 结果 unstack;④解释时同时关注样本数 count 与均值/总和,避免样本数很少导致误判。
3. tips 数据中已生成 tip_pct=tip/total_bill。请分析 day 与 smoker 组合下小费比例是否差异明显。#
参考答案:步骤:①按 [“day”,“smoker”] 分组;②对 tip_pct 计算 mean、std、极差或 describe;③比较各组均值和离散程度;④老师课堂指出仅看均值可能差异不明显,应同时看 std/极差判断组内波动。
10. 一页纸考前速览#
| 模块 | 必须记住 |
|---|---|
| 读写 | open:w 覆盖、a 追加、r 读取;read/readline/readlines 都移动指针。read_csv:sep/header/names/index_col/na_values/skiprows/nrows/chunksize。to_csv:sep/na_rep/index/header/columns。JSON:loads/dumps/read_json/to_json(orient=“records”)。 |
| 清洗思想 | 先理解数据再处理;清洗服务于分析问题。检查 head/info/describe/isna/value_counts。真实项目中清洗常是主要时间成本。 |
| 去重 | df.duplicated();df.drop_duplicates(subset=[…], keep=“first/last”)。默认按整行,第一次出现保留。保留最新记录前要先按时间排序。 |
| 映射 | df[“new”] = df[“old”].str.lower().str.strip().map(mapping)。map 可传字典或函数;键不匹配会 NaN。 |
| 替换 | s.replace(old,new);s.replace([old1,old2], np.nan);s.replace({old1 |
| 重命名 | df.rename(index=…, columns=…);df.index = df.index.map(func);不赋值且无 inplace 不改变原对象。 |
| GroupBy | groupby 是 split-apply-combine;GroupBy 对象未计算。df.groupby(“key”)[“value”].mean();多键结果 MultiIndex,可 unstack。 |
| 分组键 | 列名、外部数组/Series、字典/Series 映射、函数、level。函数键作用在索引值上;axis=1 表示按列方向。 |
| 迭代/选列 | for name, group in df.groupby(…):;单键 name 是值,多键 name 是元组。先选再分组或先分组再选列均可。 |
| 聚合 | size 行数;count 非缺失;mean/sum/std/min/max/quantile/describe。自定义:def p2p(x): return x.max()-x.min(); grouped.agg(p2p)。多列:agg({“col1”:[“mean”,“std”], “col2”:“sum”})。 |
| 易错 | header=None 忘写;sep 正则写错;大小写/空格未统一;replace 前不懂业务含义;自定义函数加括号;count/size 混淆;聚合后还用原始行索引解释。 |
考前 10 分钟背诵口径:读入看参数,清洗看问题,映射看键值,去重看 subset/keep,分组看键和索引,聚合看输出结构,解释看业务含义。
附录:课堂转录中已修正的常见误识别#
| 转录词 | 合理修正 | 依据 |
|---|---|---|
| 判断、Palace、怕能、pandas 练习 | pandas | 根据 PPT 与上下文,均指 pandas 库或 pandas 练习。 |
| google map、group back、group plan、prove | groupby | 均出现在分组聚合上下文。 |
| 缺日军、确实值、全日制 | 缺失值 | 出现在数据清洗、dropna、NaN 语境。 |
| NN、NA、NAN | np.nan / NaN | 出现在 replace 和缺失值替换语境。 |
| X 等于 1、IC 等于 1 | axis=1 | 出现在按列分组或按列 dropna 语境。 |
| in case、increase、in place | inplace=True | 出现在原地修改语境。 |
| learn/刃 | len | 出现在按字符串长度分组 people.groupby(len) 语境。 |
| pick to pick、peak pig | peak_to_peak | 出现在极差函数 max-min 语境。 |
第 4 章 数据可视化 Matplotlib#
内容来源:原文件内容。 课程 PPT《第 2 章 数据可视化 I》与 2026-03-30 课堂转录。
1. 本讲/本章知识框架#
本章的核心逻辑是:先理解 Matplotlib 图表对象的组成,再掌握常用绘图函数,随后学习如何修饰和保存图形,最后进入多子图/画布管理。
-
- Matplotlib 图表组成要素
- Figure:完整画布;单图可隐式创建,组合图通常需要显式创建。
- Axes:具体绘图区域,包含坐标系、图形元素、标题、图例等。
- Axis / tick / ticklabel / spine:坐标轴、刻度、刻度标签和坐标轴边框。
- 图形元素:plot 折线、scatter 散点、axhline/axvline 参考线、axvspan/axhspan 参考区域、annotate/text 注释。
-
- 基础绘图函数与图形定制
- plot:展示变量随顺序或时间的趋势变化。
- scatter:寻找两个变量之间的关系,点的绘制不依赖连接顺序。
- xlim/ylim、xlabel/ylabel、grid、title、legend:控制坐标范围、标签、网格、标题和图例。
- linestyle、linewidth、color、marker、alpha、dashes:通过 **kwargs 定制视觉属性。
-
- 使用统计函数绘制简单图形
- bar / barh:离散类别的数值比较;可堆积或并列。
- stackplot / step:组成随时间变化、阶梯型变化。
- hist:连续变量分布;注意与柱状图区别。
- pie / donut:构成比例;类别过多时不推荐。
- polar / bubble / boxplot:极坐标展示、三变量关系、分布与异常值。
-
- 完善统计图形
- 中文和负号显示、图例和标题、坐标范围和刻度标签、图中表格、刻度定位器与格式器。
-
- 画布和绘图区域
- figure / subplot / subplots:控制画布大小、多图布局和绘图区域。
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| Matplotlib | Matplotlib | Python 基础绘图库,提供高度可定制的二维图表绘制能力。 | 需要精细控制图表元素、做课程中的基础可视化练习。 | Seaborn 更偏统计封装;Matplotlib 更基础、更灵活。 | 为什么先学 Matplotlib 而不是只学 Seaborn? |
| pyplot | matplotlib.pyplot / plt | Matplotlib 的状态式绘图接口,课程中规范写法为 import matplotlib.pyplot as plt。 | 快速绘制单图或简单多图。 | 不要把 plt 重新赋值为绘图返回值。 | 下面代码为什么 plt.legend() 报错? |
| 画布 | Figure | 承载整张图的外层对象。 | 组合图、多子图、保存整张图时。 | 单图常隐式创建;多图应显式控制。 | Figure 与 Axes 有什么关系? |
| 绘图区域 | Axes | 实际绘制坐标系和图形元素的区域。 | 一张 figure 中可有一个或多个 axes。 | Axes 不是 axis;Axes 是区域,Axis 是轴。 | 解释 Axes 与 Axis 的区别。 |
| 坐标轴 | Axis | 表示 x 轴或 y 轴及其刻度、刻度标签。 | 设置刻度范围、刻度标签、格式。 | axis 不是 axes。 | tick 和 ticklabel 分别是什么? |
| 折线图 | Line Plot / plot() | 把一组 x-y 点按顺序连接,展示趋势变化。 | 时间序列、函数曲线、连续趋势。 | 点的顺序会影响线的连接。 | plot 适合什么数据? |
| 散点图 | Scatter Plot / scatter() | 将 x-y 点独立画出,用于观察变量关系。 | 相关关系、聚类趋势、离群点。 | 不按点顺序连接;重排样本顺序通常不改变图形。 | scatter 与 plot 的区别? |
| 线型 | linestyle / ls | 控制线条风格,如实线、虚线、点划线、点线。 | 区分多条曲线或表示参考线。 | ls=”—” 与 dashes=(…) 都可影响虚线样式。 | 写出四种常见 linestyle。 |
| 线宽 | linewidth / lw | 控制线条粗细。 | 突出重点曲线或降低辅助线存在感。 | 过粗会遮挡数据,过细不易读。 | lw 参数的作用是什么? |
| 标记 | marker | 控制折线图中每个数据点的符号。 | 样本点较少、需要突出节点时。 | marker 与 scatter 都能显示点,但语义不同。 | 什么时候给 plot 添加 marker? |
| 颜色 | color / c | 控制线、点、柱等图形元素颜色。 | 区分类别、系列、重点区域。 | 颜色名、缩写、十六进制、colormap 都可能出现。 | color 与 colormap 的区别? |
| 透明度 | alpha | 取值通常为 0–1,控制透明程度。 | 重叠点、区域标注、填充图。 | alpha=0 完全透明,alpha=1 不透明。 | 如何让 axvspan 不遮住曲线? |
| 网格线 | Grid | 根据刻度位置绘制辅助参考线。 | 读数、比较、观察趋势。 | 网格线应服务读数,不应喧宾夺主。 | grid 与 tick 的关系是什么? |
| 参考线 | axhline / axvline | 在图中绘制水平/垂直参考线。 | 阈值、均值、零线、极限线。 | 参考值来自分析问题,不是函数自动决定。 | 如何画 y=0 参考线? |
| 参考区域 | axvspan / axhspan | 高亮横向或纵向范围。 | 标注时间窗口、异常区间、关注区间。 | 要配合 alpha,避免遮挡数据。 | 如何标出 x=1 到 x=2 的关注区间? |
| 指向型注释 | annotate() | 带箭头的注释,包含被注释点 xy 和文本位置 xytext。 | 标出极值点、关键事件。 | xy 是被指对象,xytext 是文字位置。 | annotate 至少需要哪些位置信息? |
| 无指向文本 | text() | 在指定坐标处添加普通文本。 | 图内说明、局部标签。 | text 不自动生成箭头。 | text 和 annotate 有什么区别? |
| 图例 | legend() | 解释不同线、点、柱代表的系列。 | 多系列图、类别图。 | 需要 label;loc 与 bbox_to_anchor 可控制位置。 | legend 遮挡数据怎么办? |
| 柱状图 | Bar Chart / bar() | 用矩形长度比较离散类别数值。 | 类别比较、排名、分组汇总。 | 不同于直方图;柱间可有空隙。 | 柱状图和直方图区别? |
| 直方图 | Histogram / hist() | 把连续变量分箱,展示分布形态。 | 连续数值分布、偏态、集中程度。 | 不是类别比较;bin 设置会影响形态。 | bins 改变会影响什么? |
| 饼图 | Pie Chart / pie() | 用扇形面积表示部分占整体比例。 | 少量类别的构成比例。 | 类别过多可读性差;需保证整体概念。 | 饼图分块过多会怎样? |
| 箱线图 | Box Plot / boxplot() | 展示中位数、四分位数、须和异常值。 | 比较多组数值分布、离群值。 | 默认 whis=1.5,异常值判断与 IQR 相关。 | 箱线图能看出哪些分布信息? |
| 子图 | subplot / subplots | 在同一画布中创建多个绘图区域。 | 多图对比、组合展示。 | subplot(行,列,编号) 的编号从 1 开始。 | 如何创建 2×2 子图? |
3. 重点知识详解#
3.1 Matplotlib 的定位与规范导入#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | Matplotlib 是本章基础绘图库;pyplot 是常用绘图接口,规范导入为 import matplotlib.pyplot as plt,同时配合 numpy 准备数值数据。 |
| 直观理解 | 把 Matplotlib 理解为“画图底层工具箱”。Seaborn 等更高级工具可降低代码量,但许多图形元素仍可对应到 Matplotlib 的画布、坐标轴、图例、文本等概念。 |
| 典型例子 | import matplotlib.pyplot as plt; import numpy as np; x=np.linspace(0.05,10,1000); y=np.cos(x)。 |
| 可能考点 | 解释为什么基础可视化先学 Matplotlib;写出标准导入语句;说明 plt.show() 的作用。 |
| 常见错误 | 把 plt 作为普通变量名重新赋值,如 plt = plt.plot(…), 之后 plt.legend() 可能出现属性不存在。 |
| PPT中对应内容 | PPT 第5页给出准备工作;第6–17页展示 plot 基础用法。 |
| 老师课堂强调 | 老师强调 Matplotlib 虽然基础、代码稍繁,但掌握其绘图逻辑后,其他可视化包中的图表元素也能找到对应关系;脚本文件中要正式调用 legend() 和 show()。 |
| 标准答题表述 | Matplotlib 是 Python 基础绘图库,本章用它理解图表组成与绘图参数;规范使用 pyplot 接口 plt,并通过 plt.show() 显示最终图形。 |
3.2 Figure、Axes、Axis、Tick 与图表组成#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | Figure 是完整画布;Axes 是绘图区域;Axis 是具体坐标轴;tick 是刻度位置,ticklabel 是刻度显示文本,spines 是坐标轴边框。 |
| 直观理解 | Figure 像一张纸,Axes 是纸上的绘图框,Axis 是绘图框中的横轴/纵轴,tick/ticklabel 是坐标尺上的刻度和数字。 |
| 典型例子 | 单图时 plt.plot(…) 可隐式创建 Figure/Axes;组合图时更常用 fig, axes = plt.subplots(…)。 |
| 可能考点 | 解释 Figure 和 Axes 的关系;指出图中标题、图例、网格、刻度、参考线属于哪些元素。 |
| 常见错误 | 把 Axes 和 Axis 混用;只会画线而不会解释图表组成。 |
| PPT中对应内容 | PPT 第4页“Matplotlib中的常用函数”展示 figure、Axes、plot、scatter、grid、axhline、axvspan、annotate、text、title、legend、xlim、xlabel 等位置。 |
| 老师课堂强调 | 老师用 PPT 第4页图强调:单图时画布不显式声明也能创建;组合图多数情况下需要先声明画布。网格线与 tick 对应,图中标注需考虑位置、内容和指向对象。 |
| 标准答题表述 | Figure 是承载整张图的画布,Axes 是具体绘图区域,Axis 是坐标轴。图形元素、标题、图例、网格、注释等都绘制在 Figure/Axes 体系中。 |
3.3 plot():趋势变化与线条样式#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | plot(x, y) 将 x-y 对应点按给定顺序连接,用于展示变量的趋势变化。常用参数包括 ls/linestyle、lw/linewidth、label、color/c、marker、dashes。 |
| 直观理解 | plot 不是简单“画曲线”,本质是把点连起来;点的顺序决定线的路径。因此适合时间、序列、函数值等有顺序意义的数据。 |
| 典型例子 | x=np.linspace(0.05,10,1000); y=np.cos(x); plt.plot(x,y,ls=”-“,lw=2,label=“plot figure”); plt.legend(); plt.show()。 |
| 可能考点 | 根据代码判断线型、线宽、图例文本;补全 plot 绘图模板;比较 plot 与 scatter。 |
| 常见错误 | 忘记 label 导致 legend 无有效图例;x 与 y 长度不一致;把无序样本强行连线。 |
| PPT中对应内容 | PPT 第6–17页,包括 plot 调用签名、np.linspace/cos 例子、**kwargs、color、linestyle、marker。 |
| 老师课堂强调 | 老师强调 plot 体现 XY 点的映射关系,并依次连接形成趋势;legend 和 show 是正式展示图形的推荐流程;dashes=(5,2,1,2) 表示实线和空白长度组合循环。 |
| 标准答题表述 | plot() 用于绘制折线图,适合展示具有顺序意义的变量趋势;x、y 分别为坐标值,ls 控制线型,lw 控制线宽,label 供 legend 生成图例。 |
3.4 scatter() 与气泡图:变量关系与多维编码#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | scatter(x, y) 绘制散点图,用于观察两个变量之间的关系;可进一步用 s 表示点大小、c 表示颜色,从而形成气泡图或带颜色映射的散点图。 |
| 直观理解 | scatter 关心点云形态,不把点按顺序连接。样本顺序改变后,图形通常不变。 |
| 典型例子 | x=np.linspace(0.05,10,1000); y=np.random.rand(1000); plt.scatter(x,y,label=“scatter figure”); plt.legend(); plt.show()。 |
| 可能考点 | 判断变量是否有正相关、负相关、聚类或离群点;说明 scatter 与 plot 的区别;写出气泡图参数。 |
| 常见错误 | 把 c 当成固定颜色和 colormap 混用;点过多时不调 alpha 或 s,导致重叠严重。 |
| PPT中对应内容 | PPT 第18–20页为 scatter;第95–97页为气泡图;第98–101页为 colormap。 |
| 老师课堂强调 | 老师强调 scatter 是“寻找变量之间关系”,不要求把点连起来;改变样本顺序不会改变散点图形。 |
| 标准答题表述 | scatter() 用独立点表示两个变量的对应关系,适合观察相关性、聚类和离群点;如果再用点大小或颜色编码第三个变量,就可扩展为气泡图。 |
3.5 xlim/ylim、xlabel/ylabel 与 grid:坐标范围、标签和辅助读数#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | xlim/ylim 控制坐标轴显示范围;xlabel/ylabel 设置轴标签;grid 根据刻度位置绘制网格线。 |
| 直观理解 | 坐标范围决定“看哪里”,标签说明“轴表示什么”,网格线帮助读数。 |
| 典型例子 | plt.xlim(0.05,10); plt.ylim(0,1); plt.xlabel(“x_axis”); plt.ylabel(“y_axis”); plt.grid(True)。 |
| 可能考点 | 补全坐标范围和标签设置;解释为什么网格线要与刻度对应。 |
| 常见错误 | 标签缺失导致图无法独立解释;范围过窄截断数据;网格线太重影响主体。 |
| PPT中对应内容 | PPT 第21–29页依次讲 xlim、xlabel、grid。 |
| 老师课堂强调 | 老师强调 xlim/ylim 可以把图“塞满”并去掉不必要空白;网格线在股票价格曲线等复杂数据中能帮助参考读数。 |
| 标准答题表述 | xlim/ylim 设置轴显示范围,xlabel/ylabel 标明变量含义,grid 绘制刻度对应的辅助线,用于提高图形可读性。 |
3.6 axhline/axvline 与 axvspan/axhspan:参考线和参考区域#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | axhline 绘制平行于 x 轴的水平参考线,axvline 绘制垂直参考线;axvspan/axhspan 绘制纵向/横向参考区域。 |
| 直观理解 | 参考线用于标出阈值、零线、均值等;参考区域用于突出一段时间窗口或重点区间。 |
| 典型例子 | plt.axhline(y=0, ls=”—”, c=“r”); plt.axvspan(1, 2, alpha=0.2)。 |
| 可能考点 | 根据分析情境选择 y=0、均值线或阈值线;用 axvspan 标注 x 的一段区间。 |
| 常见错误 | 认为参考值由绘图函数决定;忘记设置 alpha 导致参考区域遮挡曲线。 |
| PPT中对应内容 | PPT 第30–35页讲 axhline 与 axvspan。 |
| 老师课堂强调 | 老师强调 axhline 中 h 是 horizontal;参考线/区域的取值依赖对数据和业务问题的理解,例如股价上升/下降区间。 |
| 标准答题表述 | 参考线和参考区域是分析解释层面的图形元素,其位置由研究问题决定;Matplotlib 只负责把指定位置画出来。 |
3.7 annotate()、text()、title() 与 legend():图中解释信息#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | annotate 添加带箭头的指向型注释;text 添加无指向文本;title 添加图标题;legend 根据 label 添加图例。 |
| 直观理解 | 图形不是只看数据点,还要让读者知道“重点在哪里”“每条线代表什么”“整张图讲什么”。 |
| 典型例子 | plt.annotate(“maximum”, xy=(x0,y0), xytext=(x1,y1), arrowprops={“arrowstyle”:”->”}); plt.legend(loc=“upper center”, bbox_to_anchor=(0.6,0.95), ncol=3)。 |
| 可能考点 | 解释 xy 与 xytext;根据图例遮挡问题调整 loc/bbox_to_anchor;说明 label 与 legend 的关系。 |
| 常见错误 | xy 和 xytext 写反;legend 没有 label;图例遮挡主体却不调整位置。 |
| PPT中对应内容 | PPT 第36–50页讲 annotate、text、title、legend 和 bbox_to_anchor 示例。 |
| 老师课堂强调 | 老师强调 annotate 需要知道被注释位置、文本位置以及箭头属性;legend 可默认选择位置,也可用 loc 与 bbox_to_anchor 精确放置,bbox_to_anchor 四元组前两个值是位置,后两个值是宽高。 |
| 标准答题表述 | annotate 用于带箭头标注关键点,text 用于直接放置文本,title 给出图标题,legend 通过 label 解释不同图形系列。 |
3.8 图形保存 savefig()#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | savefig 将当前图形保存为图片或其他格式,常与 dpi、bbox_inches 等参数配合。 |
| 直观理解 | show 是“显示出来”,savefig 是“保存到文件”。报告或作业中通常需要保存清晰图片。 |
| 典型例子 | plt.savefig(“result.png”, dpi=300, bbox_inches=“tight”)。 |
| 可能考点 | 补全保存图形代码;解释 dpi 和 bbox_inches=“tight” 的用途。 |
| 常见错误 | 在某些环境中先 show 后 save 可能保存空白图;文件路径错误;dpi 太低。 |
| PPT中对应内容 | PPT 第56页“图形的保存”。 |
| 老师课堂强调 | 课堂转录前半部分对保存未充分展开;此处主要依据 PPT 与课程绘图流程整理。 |
| 标准答题表述 | savefig() 用于把图形写入文件,常在 plt.show() 前调用,并通过 dpi 控制清晰度,通过 bbox_inches=“tight” 减少边缘空白。 |
3.9 bar()/barh():柱状图、堆积柱状图与并列柱状图#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | bar 绘制垂直柱状图,barh 绘制水平条形图;bottom 可实现堆积柱状图,调整 x 位置和 width 可实现并列柱状图。 |
| 直观理解 | 柱状图比较离散类别的数值大小;堆积柱状图看总量及构成;并列柱状图看同类别下多个系列的横向比较。 |
| 典型例子 | plt.bar(x, y); plt.bar(x, y1, bottom=y); plt.bar(x-width/2, y, width); plt.bar(x+width/2, y1, width)。 |
| 可能考点 | 判断应使用堆积还是并列;解释 bottom 参数;补全并列柱状图的位置偏移。 |
| 常见错误 | 把连续变量分布画成柱状图;并列柱的 x 偏移没对齐 tick;堆积时 bottom 写错系列。 |
| PPT中对应内容 | PPT 第58–67页讲 bar、堆积柱状图、颜色表示、多数据并列柱状图;第71–73页讲 barh。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖统计函数部分;此处主要依据 PPT 整理。 |
| 标准答题表述 | 柱状图用于离散类别比较;堆积柱状图通过 bottom 把后一组柱子建立在前一组之上;并列柱状图通过对 x 位置做左右偏移展示多组数据。 |
3.10 stackplot() 与 step():构成变化和阶梯变化#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | stackplot 绘制堆积折线/面积图;step 绘制阶梯图,where 参数控制阶梯位于 pre、mid 或 post。 |
| 直观理解 | stackplot 适合看总量变化和各部分贡献;step 适合状态、等级、价格等分段常量型变化。 |
| 典型例子 | plt.stackplot(x, y1, y2, labels=[…]); plt.step(x, y, where=“mid”)。 |
| 可能考点 | 根据数据变化形态选择 stackplot 或 step;解释 where 参数。 |
| 常见错误 | 用普通折线图表示本应分段保持不变的数据;堆积图类别过多导致难读。 |
| PPT中对应内容 | PPT 第68–70页讲 stackplot;第74–76页讲 step 以及 step 与 plot(drawstyle) 的关系。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖该后续部分。 |
| 标准答题表述 | stackplot 用于展示多个组成部分随 x 的累计变化;step 用于展示变量在区间内保持不变、到节点才跳变的阶梯式过程。 |
3.11 hist() 与“直方图 vs 柱状图”#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | hist 对连续变量分箱并统计频数或密度;histtype 可选 bar、barstacked、step、stepfilled。 |
| 直观理解 | 直方图回答“数值分布在哪里集中、偏不偏、有没有长尾”;柱状图回答“不同类别谁大谁小”。 |
| 典型例子 | plt.hist(data, bins=20, histtype=“bar”, alpha=0.8)。 |
| 可能考点 | 解释直方图和柱状图区别;分析 bins 对图形的影响;判断何时用 hist。 |
| 常见错误 | 把类别频数图称为直方图;忽略 bins 会影响分布视觉;用柱状图比较连续变量分布。 |
| PPT中对应内容 | PPT 第77–82页讲 hist、histtype,并回顾直方图与柱状图区别:直方图描述连续型数据分布,柱状图描述离散型数据分布。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖 hist 部分。 |
| 标准答题表述 | 直方图用于连续数据分布,柱状图用于离散类别比较;直方图的横轴是连续区间,柱状图的横轴是类别。 |
3.12 pie() 与内嵌环形饼图#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | pie 用扇形展示整体中的组成比例;内嵌环形饼图通过 wedgeprops 或中心圆效果形成环形结构。 |
| 直观理解 | 饼图适合回答“各部分占整体多少”,不适合精确比较多个相近数值。 |
| 典型例子 | plt.pie(values, labels=labels, autopct=“%1.1f%%”, startangle=90); plt.axis(“equal”)。 |
| 可能考点 | 如何让饼图变圆;类别过多时的局限;autopct/startangle/pctdistance 的含义。 |
| 常见错误 | 类别过多仍使用饼图;没有 equal 导致椭圆;把非整体构成数据画成饼图。 |
| PPT中对应内容 | PPT 第83–91页讲 pie、startangle、让饼图变圆、分块过多问题、内嵌环形饼图、pctdistance、setp。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖饼图部分。 |
| 标准答题表述 | pie() 适用于少量类别构成比例展示;饼图应确保各部分构成一个整体,且类别不宜过多。 |
3.13 polar()、气泡图与 colormap#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | polar 使用极坐标绘图;气泡图用散点的大小或颜色编码额外变量;colormap 将数值映射到颜色。 |
| 直观理解 | 在二维 x-y 坐标外,颜色和大小可作为额外视觉通道,但要避免同时编码过多维度。 |
| 典型例子 | plt.scatter(x, y, s=size, c=value, cmap=“viridis”, alpha=0.7); plt.colorbar()。 |
| 可能考点 | 四类 colormap 的适用场景;气泡图中 s 和 c 分别表示什么;为什么要加 colorbar。 |
| 常见错误 | 把连续变量用定性色图;有颜色映射却不加 colorbar;气泡面积误导读者。 |
| PPT中对应内容 | PPT 第92–101页讲 polar、气泡图以及 Sequential、Diverging、Qualitative、Miscellaneous colormaps。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖该部分。 |
| 标准答题表述 | 连续变量通常选 Sequential colormap;以 0 等中点为分界的正负变量可用 Diverging;离散类别可用 Qualitative。 |
3.14 boxplot():箱线图与异常值#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 箱线图展示中位数、上下四分位数、须和异常值;PPT 标注默认 whis=1.5。 |
| 直观理解 | 一张箱线图压缩展示分布中心、离散程度、偏态和离群点,多组箱线图便于横向比较。 |
| 典型例子 | plt.boxplot([data1, data2], labels=[“A”,“B”], whis=1.5)。 |
| 可能考点 | 解释箱体、箱线、中位数、须和异常点;根据箱线图比较两组分布。 |
| 常见错误 | 只看均值而忽略分布;误以为异常点一定是错误数据;不知道 whis 与 IQR 的关系。 |
| PPT中对应内容 | PPT 第102–106页讲 boxplot,默认 whis=1.5,并涉及 ticks 与 labels。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖箱线图部分。 |
| 标准答题表述 | 箱线图用五数概括及异常点展示数值分布,适合多组分布比较;默认 whis=1.5 时,异常点通常与 IQR 判定有关。 |
3.15 完善统计图形:中文、标题图例、刻度与图中表格#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 完善图形包括设置字体和负号、添加标题和图例、调整坐标轴范围和刻度标签、在图中添加表格、设置刻度定位器与格式器。 |
| 直观理解 | 作业或考试图形不仅要“能画出来”,还要能让读者独立读懂。 |
| 典型例子 | plt.rcParams[“font.sans-serif”]=[“SimHei”]; plt.rcParams[“axes.unicode_minus”]=False; plt.xticks(x, labels, rotation=45)。 |
| 可能考点 | 中文乱码和负号显示如何处理;如何旋转 x 轴标签;如何设置主/次刻度。 |
| 常见错误 | 中文无法显示;x tick 与标签数量不一致;标签过长重叠;刻度过密。 |
| PPT中对应内容 | PPT 第108–128页讲添加图例和标题、中文/符号显示、刻度范围和标签、图中表格、刻度定位器与格式器。 |
| 老师课堂强调 | 本次课堂转录未充分覆盖该部分;但老师在前半段强调图例位置要结合图中内容,不要遮挡主体。 |
| 标准答题表述 | 完善统计图形的目标是提高可读性和可解释性:标题说明主题,轴标签说明变量,图例说明系列,刻度与网格辅助读数,字体设置保证正常显示。 |
3.16 Figure 与 subplot:多图布局#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | subplot 用于在网格区域中创建多个几何形状相同的子区布局;subplots 更适合一次性创建 figure 与 axes 数组。 |
| 直观理解 | 多图布局适合横向对比:同一数据不同图、不同类别同一指标、不同时间段同一趋势。 |
| 典型例子 | plt.subplot(2,2,1); plt.plot(…); plt.subplot(2,2,2); plt.scatter(…); 或 fig, axes = plt.subplots(2,2)。 |
| 可能考点 | 解释 subplot(2,2,3) 的含义;补全 2×2 子图代码;说明为何多图需要显式画布。 |
| 常见错误 | 编号从 0 开始写;多个子图共用状态式 plt 时画错区域;忘记 tight_layout。 |
| PPT中对应内容 | PPT 第129–133页讲画布和绘图区域、subplot。 |
| 老师课堂强调 | 老师在开头强调:绘制单图时画布不重要,但组合图多数情况下需要声明画布。 |
| 标准答题表述 | subplot 将一张 Figure 划分为行列网格,并在指定编号位置绘制子图;多图比较时应显式管理画布与绘图区域。 |
4. Python 实现与代码模板#
说明:PPT/转录给出部分示例代码;以下模板按课程内容整理为可直接套用版本。涉及对象式写法、完整图形美化和真实数据流程的代码标注为“根据课程内容整理的通用模板”。
4.1 基础折线图:plot()(PPT/课堂示例整理)#
# 输入:x、y 两个等长一维数组# 输出:一张带图例的折线图# 用途:展示函数值、时间序列或有顺序意义变量的趋势变化import matplotlib.pyplot as pltimport numpy as np
x = np.linspace(0.05, 10, 1000)y = np.cos(x)
plt.plot(x, y, ls='-', lw=2, label='plot figure')plt.legend()plt.show()
# 易错点:不要写 plt = plt.plot(...)# 常见报错:ValueError: x and y must have same first dimension4.2 散点图:scatter()(PPT/课堂示例整理)#
# 输入:x、y 两个等长一维数组# 输出:散点图# 用途:观察两个变量之间的相关性、聚类和离群点import matplotlib.pyplot as pltimport numpy as np
x = np.linspace(0.05, 10, 1000)y = np.random.rand(1000)
plt.scatter(x, y, c='b', label='scatter figure')plt.legend()plt.show()
# 易错点:scatter 不会按照样本顺序连线;重排样本顺序通常不改变图形。4.3 图形完善:范围、标签、网格、参考线/区域(根据课程内容整理的通用模板)#
# 输入:x、y# 输出:带坐标范围、标签、网格、参考线和参考区域的图# 用途:完整表达变量含义,并突出阈值/关注区间plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')plt.xlim(0.05, 10)plt.ylim(-1.1, 1.1)plt.xlabel('x_axis')plt.ylabel('y_axis')plt.title('Trend with Reference')plt.grid(True, linestyle='--', alpha=0.5)plt.axhline(y=0, ls='--', c='r', lw=1, label='y=0')plt.axvspan(2, 4, alpha=0.2, label='focus interval')plt.legend(loc='best')plt.show()
# 易错点:axvspan(xmin, xmax) 是 x 方向区间;alpha 建议小一些,避免遮挡主体。4.4 注释:annotate() 与 text()#
# 输入:被注释点坐标 (x0, y0) 与文本位置 (x1, y1)# 输出:带箭头注释和普通文本的图plt.plot(x, y, label='curve')
x0, y0 = x[np.argmax(y)], np.max(y)plt.annotate('maximum', xy=(x0, y0), xytext=(x0+0.8, y0-0.3), arrowprops={'arrowstyle': '->'}, weight='bold')plt.text(0.5, -0.8, 'note text', color='gray')plt.legend()plt.show()
# annotate: xy 是被注释对象坐标;xytext 是注释文字坐标。# text: 只有文字,没有自动箭头。4.5 图例位置:loc 与 bbox_to_anchor(PPT/课堂重点)#
# 输入:多条已设置 label 的曲线# 输出:自定义位置和形态的图例plt.plot(x, np.sin(x), label='sin')plt.plot(x, np.cos(x), label='cos')plt.plot(x, np.sin(2*x), label='sin(2x)')plt.plot(x, np.cos(2*x), label='cos(2x)')
plt.legend(loc='upper center', bbox_to_anchor=(0.6, 0.95), ncol=3, fancybox=True, shadow=True)plt.show()
# bbox_to_anchor=(x, y, width, height) 时,前两个值控制锚点位置,后两个值控制框大小。# 只有两个值时,主要用于指定锚点相对位置。4.6 柱状图:bar()、堆积与并列(根据课程内容整理的通用模板)#
# 输入:类别标签 labels 和数值 values# 输出:柱状图 / 堆积柱状图 / 并列柱状图import numpy as npimport matplotlib.pyplot as plt
labels = ['A', 'B', 'C', 'D']y1 = np.array([10, 14, 8, 12])y2 = np.array([6, 9, 5, 7])x = np.arange(len(labels))width = 0.35
# 并列柱状图plt.bar(x - width/2, y1, width=width, label='group 1')plt.bar(x + width/2, y2, width=width, label='group 2')plt.xticks(x, labels)plt.ylabel('value')plt.legend()plt.show()
# 堆积柱状图:第二组从第一组顶部开始plt.bar(x, y1, label='group 1')plt.bar(x, y2, bottom=y1, label='group 2')plt.xticks(x, labels)plt.legend()plt.show()
# 易错点:并列图要移动 x 位置;堆积图用 bottom 指定基底。4.7 直方图:hist()#
# 输入:一维连续数值数据 data# 输出:直方图# 用途:观察连续变量分布、偏态、集中程度、离群区间plt.hist(data, bins=20, histtype='bar', alpha=0.8)plt.xlabel('value')plt.ylabel('frequency')plt.title('Histogram')plt.show()
# histtype 可选:'bar', 'barstacked', 'step', 'stepfilled'# 易错点:直方图用于连续变量分布,不等同于类别柱状图。4.8 饼图与环形饼图:pie()#
# 输入:组成部分 values 和标签 labels# 输出:饼图或环形饼图values = [35, 25, 20, 20]labels = ['A', 'B', 'C', 'D']
plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=90, pctdistance=0.75)plt.axis('equal') # 让饼图变圆plt.show()
# 环形饼图:通过 wedgeprops 设置宽度plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=90, wedgeprops={'width': 0.35})plt.axis('equal')plt.show()
# 易错点:类别过多或数值不是整体构成时,不宜使用饼图。4.9 箱线图:boxplot()#
# 输入:多个一维数值数组# 输出:箱线图# 用途:比较多组数据的中位数、四分位数、离散程度和异常值plt.boxplot([data_a, data_b, data_c], labels=['A', 'B', 'C'], whis=1.5)plt.ylabel('value')plt.title('Boxplot')plt.show()
# 易错点:异常点不一定是错误数据;箱线图展示的是分布,不是只比较均值。4.10 子图:subplots()(根据课程内容整理的通用模板)#
# 输入:多个图形任务# 输出:2×2 子图布局# 用途:在同一画布中比较不同图或不同变量fig, axes = plt.subplots(2, 2, figsize=(10, 6))
axes[0, 0].plot(x, np.sin(x))axes[0, 0].set_title('line')
axes[0, 1].scatter(x, np.random.rand(len(x)), s=5)axes[0, 1].set_title('scatter')
axes[1, 0].hist(data, bins=20)axes[1, 0].set_title('hist')
axes[1, 1].boxplot([data_a, data_b], labels=['A', 'B'])axes[1, 1].set_title('box')
fig.tight_layout()plt.show()
# 补充理解:对象式写法更适合复杂多图;课程前半部分主要使用 pyplot 状态式写法。4.11 保存图形:savefig()#
# 输出:适合报告/作业插入的图片文件plt.savefig('figure.png', dpi=300, bbox_inches='tight')plt.show()
# 易错点:建议先 savefig 再 show;保存路径不存在会报错。5. 图表/方法选择指南#
| 数据/问题类型 | 优先图表或方法 | 重点观察 | 答题提醒 |
|---|---|---|---|
| 一个连续变量的分布 | hist(), boxplot() | 均值/中位数、分位数、偏态、异常值 | 考试中常问直方图 vs 箱线图:前者看分布形状,后者便于多组比较。 |
| 两个连续变量关系 | scatter() | 相关趋势、聚类、离群点 | 若有顺序或时间意义再考虑 plot。 |
| 时间/顺序上的趋势变化 | plot(), step() | 上升/下降、周期、突变 | 分段常量或状态变化更适合 step。 |
| 离散类别的数值比较 | bar(), barh() | 类别差异、排序、最大/最小 | 类别名很长时用 barh。 |
| 同一类别下多组比较 | 并列柱状图 | 组间差异、交互比较 | 注意 x 位置偏移与 tick 标签对齐。 |
| 总量及构成比较 | 堆积柱状图、stackplot | 总量变化、组成贡献 | 类别过多时堆积图难读。 |
| 少量类别占整体比例 | pie(), donut | 比例构成 | 类别过多或需精确比较时改用 bar。 |
| 需要突出阈值/均值/零线 | axhline(), axvline() | 参考基准、越界判断 | 参考值来自业务/统计分析。 |
| 需要突出区间 | axvspan(), axhspan() | 重点时间窗、异常区间 | 设置 alpha,避免遮挡主体。 |
| 需要解释关键点 | annotate() | 极值、异常点、事件点 | xy 与 xytext 不能混淆。 |
| 多组数值分布比较 | boxplot() | 中位数、IQR、离群点 | 不要只用均值比较。 |
| 三变量关系 | scatter(s=…, c=…), colorbar() | 位置、大小、颜色三通道 | 颜色映射需选择合适 colormap。 |
| 多图对比 | subplot(), subplots() | 不同图形/变量/分组并列呈现 | 需要显式管理 Figure/Axes。 |
6. 公式与指标总结#
| 公式/指标 | 表达式 | 符号含义 | 适用条件 | 直观解释 | 计算/实现步骤 | 考试易错点 |
|---|---|---|---|---|---|---|
| 折线图点连接逻辑 | 给定点 (x_i, y_i),按数组顺序依次连接。 | x_i,y_i 为对应坐标;i 表示样本/顺序位置。 | 有顺序意义的数据。 | 强调趋势;顺序改变会改变线。 | 准备 x/y → plot → 设置样式 → legend/show。 | 把无序样本连线。 |
| 饼图扇形角度 | angle_i = value_i / Σ value_i × 360° | value_i 为第 i 类数值;Σ value_i 为整体总量。 | 部分构成整体,且类别较少。 | 数值占比越大,扇形角越大。 | 求总量 → 算比例 → 映射角度/面积。 | 数据不是整体构成却画饼图。 |
| 直方图分箱频数 | count_j = 落入第 j 个 bin 的样本数 | bin 为连续区间;count_j 为频数。 | 连续变量分布。 | 把连续数据压缩为区间频数。 | 设 bins → 统计每箱频数 → 绘制矩形。 | bins 过大/过小导致误读。 |
| 直方图密度(补充理解) | density_j ≈ count_j / (n × bin_width_j) | n 为样本数;bin_width 为箱宽。 | 需要面积归一化的分布比较。 | 不同样本量/箱宽下可比。 | hist(…, density=True)。 | 把密度当频数。 |
| IQR 与箱线图异常值 | IQR = Q3 - Q1;默认 whis=1.5 时参考区间约为 [Q1-1.5IQR, Q3+1.5IQR] | Q1/Q3 为四分位数;IQR 为四分位距。 | 箱线图默认异常值判断。 | 箱体表示中间 50% 数据,须外点通常视为异常点。 | 算 Q1/Q3 → IQR → 上下界 → 判断异常点。 | 异常点不等于错误数据。 |
| 并列柱位置偏移 | x_left = x - width/2;x_right = x + width/2 | x 为类别中心;width 为柱宽。 | 两组并列柱状图。 | 围绕类别中心左右错开。 | 构造 x=np.arange(n) → 左右偏移 → xticks(x, labels)。 | tick 放在偏移后位置导致标签错位。 |
| 堆积柱 bottom | 第二组高度起点 = 第一组高度 bottom=y1 | y1 为下层柱高;y2 为上层柱高。 | 看总量及构成。 | 后一组柱子不是从 0 开始,而是从前一组顶部开始。 | plt.bar(x,y1); plt.bar(x,y2,bottom=y1)。 | bottom 写成 y2 或漏写。 |
| 透明度 alpha | 0 ≤ alpha ≤ 1 | 0 完全透明,1 完全不透明。 | 散点重叠、区域高亮、填充图。 | 降低遮挡,保留上下层信息。 | alpha=0.2/0.5 等。 | alpha 太高遮挡主体。 |
| bbox_to_anchor 四元组 | (x, y, width, height) | x,y 为锚点位置;width,height 为图例框宽高。 | 图例精确定位。 | loc 决定图例框上的锚点,bbox_to_anchor 给该锚点在坐标系中的位置。 | 先定 loc → 再定 bbox_to_anchor → 调 ncol/fancybox/shadow。 | 把 loc 和 bbox_to_anchor 的角色混淆。 |
7. 课堂重点与考试提示#
以下重点主要来自课堂转录;对 PPT 后半部分未充分展开之处,已单独标注。
必背概念#
| 类别 | 重点 |
|---|---|
| Matplotlib 的基础性 | 它是更高级绘图库的底层基础;掌握图表元素和参数逻辑后,可迁移到其他包。 |
| Figure / Axes / Axis | Figure 是画布,Axes 是绘图区域,Axis 是坐标轴。 |
| plot 与 scatter | plot 连接有顺序的点,scatter 独立绘制点云;散点图不依赖样本顺序。 |
| tick / ticklabel / grid | 网格线与刻度位置对应,用于辅助读数。 |
| annotate 与 text | annotate 有被注释点和文本位置,可带箭头;text 只在指定坐标写文本。 |
| legend 与 label | label 是系列名称,legend() 根据 label 生成图例;loc/bbox_to_anchor 控制位置。 |
必会代码#
| 类别 | 重点 |
|---|---|
| 标准导入 | import matplotlib.pyplot as plt; import numpy as np |
| 显示流程 | plt.plot/scatter/… → plt.legend() → plt.show()。脚本文件尤其要 show。 |
| 坐标与标签 | plt.xlim(); plt.ylim(); plt.xlabel(); plt.ylabel(); plt.grid()。 |
| 参考线/区域 | plt.axhline(y=…); plt.axvline(x=…); plt.axvspan(xmin,xmax,alpha=…)。 |
| 图例位置 | plt.legend(loc=“upper center”, bbox_to_anchor=(0.6,0.95), ncol=3)。 |
| 统计图 | bar/bottom/width,hist/bins/histtype,pie/autopct/startangle/equal,boxplot/whis。 |
必会分析思路#
| 类别 | 重点 |
|---|---|
| 先判断数据类型 | 连续、离散、时间/顺序、构成比例、多组分布决定图表选择。 |
| 先画主体再完善 | 先 plot/scatter/bar 等画数据,再加标题、坐标轴、图例、网格、注释、范围。 |
| 图形服务解释 | 参考线和参考区域的位置来自业务或数据分析,不是绘图函数自动决定。 |
| 图例位置要避让数据 | 默认位置不一定最优;必要时将图例放到图外或指定锚点。 |
高频易错点#
| 类别 | 重点 |
|---|---|
| plt 被覆盖 | 错误:plt = plt.plot(…); 正确:不要用 plt 作变量名。 |
| legend 无内容 | 没有 label 或 label 以下划线开头时,legend 可能无有效项。 |
| plot/scatter 混用 | 无序样本不要用 plot 连线。 |
| 坐标范围误导 | xlim/ylim 过窄会截断数据,过宽会产生大量空白。 |
| 直方图/柱状图混淆 | 直方图连续变量分布;柱状图离散类别比较。 |
| 中文乱码 | 需要设置中文字体和 axes.unicode_minus。 |
可能出题方式#
| 类别 | 重点 |
|---|---|
| 概念题 | 解释 Matplotlib 图表组成;比较 plot/scatter、hist/bar、annotate/text。 |
| 代码题 | 补全 plot/scatter/bar/hist/pie/boxplot 代码;找出 plt 覆盖错误。 |
| 读图题 | 根据图形判断趋势、关系、分布、异常点、类别差异。 |
| 应用题 | 给定数据分析场景,选择合适图表并写出绘图步骤。 |
| 参数题 | 解释 linestyle、lw、marker、alpha、bottom、bins、whis、bbox_to_anchor。 |
8. 期末复习版精简笔记#
- Matplotlib 是基础绘图库;规范导入:import matplotlib.pyplot as plt;import numpy as np。
- Figure 是画布,Axes 是绘图区域,Axis 是坐标轴;单图可隐式创建,多图应显式管理。
- plot(x,y) 连点成线,适合趋势/时间/函数;scatter(x,y) 画点云,适合变量关系,不依赖点顺序。
- 常用样式:ls/linestyle 控线型,lw/linewidth 控粗细,color/c 控颜色,marker 控点样式,alpha 控透明度,label 给 legend 用。
- 正式绘图流程:准备数据 → 画主体 → 加 label/title/xlabel/ylabel/grid/legend → savefig/show。
- xlim/ylim 控制显示范围;xlabel/ylabel 说明变量;grid 与 tick 对应,辅助读数。
- axhline/axvline 画参考线;axvspan/axhspan 画参考区域;位置由数据分析/业务问题决定。
- annotate(text, xy=被指点, xytext=文字位置, arrowprops=箭头属性);text(x,y,s) 只写普通文字。
- legend 依赖 label;loc 选择图例框锚点,bbox_to_anchor 精确定位;图例不能遮挡主体。
- bar:离散类别比较;barh:类别名长或横向比较;bottom:堆积;x±width/2:并列。
- hist:连续变量分布;bins 影响形态;histtype 可选 bar/barstacked/step/stepfilled。直方图 ≠ 柱状图。
- pie:少量类别构成比例;startangle 控起始角,autopct 显示比例,axis(“equal”) 让饼图变圆;类别过多不推荐。
- scatter 可扩展为气泡图:s 表示大小,c/cmap 表示颜色映射,colorbar 解释颜色。连续变量用 sequential,正负发散用 diverging,类别用 qualitative。
- boxplot:看中位数、IQR、须、异常点;默认 whis=1.5;异常点不一定是错误数据。
- 中文显示:plt.rcParams[“font.sans-serif”]=[“SimHei”];plt.rcParams[“axes.unicode_minus”]=False。
- subplot(2,2,1) 表示 2 行 2 列第 1 个子图,编号从 1 开始;复杂多图用 fig, axes = plt.subplots(…)。
9. 自测题与参考答案
题目尽量贴近 PPT 与课堂讲法,覆盖概念题、代码题、分析题和应用题。
9.1 选择题#
| 题号 | 题目 | 答案 | 解析 |
|---|---|---|---|
| 1 | 关于 Figure 与 Axes,下列说法正确的是:A. Axis 是画布 B. Figure 是完整画布 C. Axes 与 Axis 完全同义 D. 一个 Figure 只能有一个 Axes | B | Figure 是完整画布;Axes 是绘图区域;Axis 是坐标轴。一个 Figure 可包含多个 Axes。 |
| 2 | 下列最适合展示时间序列趋势的是:A. pie B. hist C. plot D. boxplot | C | plot 将点按顺序连接,适合趋势变化。 |
| 3 | scatter() 与 plot() 的关键区别是:A. scatter 只能画连续线 B. plot 不需要 x C. scatter 不按顺序连线 D. plot 不能设置颜色 | C | scatter 独立绘制点,用于变量关系;plot 按顺序连点。 |
| 4 | 下列哪个参数通常用于堆积柱状图?A. bottom B. bins C. whis D. startangle | A | bottom 指定柱子起始高度,用于堆积。 |
| 5 | 直方图主要用于:A. 离散类别比较 B. 连续变量分布 C. 整体构成比例 D. 多子图布局 | B | hist() 对连续变量分箱,展示分布。 |
| 6 | boxplot() 中默认 whis=1.5 通常与下列哪项有关?A. IQR B. 颜色映射 C. 图例列数 D. 饼图角度 | A | 箱线图异常值判定通常使用四分位距 IQR。 |
9.2 判断题#
| 题号 | 判断题 | 答案 | 解析 |
|---|---|---|---|
| 1 | 在脚本文件中,绘图后通常需要调用 plt.show() 才能正式显示图形。 | 对 | 课堂特别提醒脚本文件中要 show。 |
| 2 | 如果样本顺序被打乱,散点图一定会完全改变。 | 错 | scatter 不连线,点集相同则图形通常不变。 |
| 3 | 直方图和柱状图本质完全相同,只是名称不同。 | 错 | 直方图看连续变量分布;柱状图比较离散类别。 |
| 4 | alpha 越小,图形元素越透明。 | 对 | alpha 通常 0–1,0 完全透明,1 不透明。 |
| 5 | plt.legend() 不需要任何 label,也一定能生成有意义图例。 | 错 | legend 依赖绘图元素的 label。 |
9.3 简答题#
| 题号 | 题目 | 参考答案 |
|---|---|---|
| 1 | 简述 Matplotlib 中 Figure、Axes、Axis 的区别。 | Figure 是完整画布,Axes 是画布中的具体绘图区域,Axis 是 Axes 中的横轴或纵轴。一个 Figure 可以包含多个 Axes,每个 Axes 通常包含 x/y 两个 Axis。 |
| 2 | 为什么老师说 Matplotlib 虽然基础但仍要讲? | 因为 Matplotlib 是 Python 可视化的基础包,许多更高级库建立在其概念和对象体系之上。掌握它的画布、坐标轴、图例、注释、参数设置后,可以迁移理解其他绘图库能设置什么以及怎样设置。 |
| 3 | 说明 annotate() 与 text() 的区别。 | annotate 是指向型注释,通常包含被注释对象坐标 xy、文本位置 xytext 和 arrowprops;text 是在指定坐标直接添加普通文本,不自动生成箭头。 |
| 4 | 说明 hist() 与 bar() 的区别。 | hist 用于连续变量分布,把数值按区间分箱统计;bar 用于离散类别数值比较,横轴通常是类别。 |
9.4 代码阅读题 1:指出错误并修改#
import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0.05, 10, 1000)y = np.cos(x)plt = plt.plot(x, y, label='cos')plt.legend()plt.show()答案与解析:错误在于 plt = plt.plot(…) 覆盖了原来的 pyplot 模块别名。之后 plt 已不再是 matplotlib.pyplot,因此 plt.legend() 可能报错。正确写法是直接调用 plt.plot(x, y, label=“cos”),不要赋值给 plt。
9.4 代码阅读题 2:这段代码是否形成堆积柱状图?如何修改?#
x = np.arange(4)y1 = np.array([10, 14, 8, 12])y2 = np.array([6, 9, 5, 7])plt.bar(x, y1, label='A')plt.bar(x, y2, label='B')plt.legend()plt.show()答案与解析:没有形成堆积柱状图,两组柱子从同一基线开始,会重叠。堆积柱状图应把第二组的 bottom 设为第一组:plt.bar(x, y2, bottom=y1, label=“B”)。
9.5 代码补全题 1#
# 代码补全:绘制 y=sin(x) 的折线图,设置线型为点划线、线宽为2,添加图例、x/y 标签和网格。import matplotlib.pyplot as pltimport numpy as npx = np.linspace(0.05, 10, 1000)y = np.sin(x)plt.plot(____, ____, ls=____, lw=____, label='sin')plt.xlabel(____)plt.ylabel(____)plt.grid(____)plt.legend()plt.show()参考答案:plt.plot(x, y, ls=”-.”, lw=2, label=“sin”); plt.xlabel(“x_axis”); plt.ylabel(“y_axis”); plt.grid(True)。
9.5 代码补全题 2#
# 代码补全:绘制两组并列柱状图,并把类别标签放在每组中心。labels = ['A', 'B', 'C']y1 = np.array([3, 5, 4])y2 = np.array([4, 2, 6])x = np.arange(len(labels))width = 0.35plt.bar(____, y1, width=width, label='G1')plt.bar(____, y2, width=width, label='G2')plt.xticks(____, ____)plt.legend()plt.show()参考答案:x - width/2;x + width/2;x;labels。解析:并列柱围绕类别中心左右偏移,tick 仍放在中心 x。
9.6 数据分析应用题#
| 题号 | 题目 | 参考答案与步骤 |
|---|---|---|
| 1 | 给定每月销售额,希望展示一年变化趋势,并标出销售额均值线。应该选什么图?写出答题步骤。 | 选 plot 折线图,并用 axhline 标均值线。步骤:准备月份 x 与销售额 y → plt.plot(x,y,label=“sales”) → mean_y=np.mean(y) → plt.axhline(mean_y,ls=”—“,label=“mean”) → 设置 xlabel/ylabel/title/grid/legend → show/savefig。 |
| 2 | 给定不同学院学生的平均成绩和标准差,希望比较学院差异。应该怎么画? | 可先用 bar 比较各学院平均值;如材料涉及误差线,可使用 errorbar 或 bar 的 yerr(若 PPT 未充分说明 errorbar,则作为补充理解)。答题时说明 x 为学院类别,y 为平均成绩,误差表示标准差。 |
| 3 | 给定一列学生成绩,希望看整体分布、偏态和异常高低分。应该选什么图? | 先用 hist 看连续分布形态,再用 boxplot 看中位数、IQR 和异常点。说明直方图看分布形态,箱线图便于概括和多组比较。 |
| 4 | 给定四类消费占总支出的比例,且类别很少,应该选什么图?若类别增加到二十类怎么办? | 四类构成比例可用 pie 或 donut,并设置 autopct、axis(“equal”)。若二十类,则饼图可读性差,建议改用按比例排序的 bar/barh。 |
10. 一页纸考前速览#
| 模块 | 考前必须看 |
|---|---|
| 基础对象 | Figure=画布;Axes=绘图区域;Axis=坐标轴;tick=刻度;ticklabel=刻度文本;spines=边框。 |
| 规范流程 | import matplotlib.pyplot as plt; import numpy as np → 准备数据 → 画主体 → 修饰 → legend/savefig/show。 |
| plot | plt.plot(x,y,ls=”-“,lw=2,label=”…”);适合趋势;点顺序重要。 |
| scatter | plt.scatter(x,y,c=“b”,s=…,alpha=…,label=”…”);适合变量关系;不连线。 |
| 坐标/网格 | xlim/ylim 控范围;xlabel/ylabel 控轴说明;title 控标题;grid 依刻度辅助读数。 |
| 参考线/区域 | axhline(y=…)、axvline(x=…)、axvspan(xmin,xmax,alpha=…);值来自分析问题。 |
| 注释 | annotate(text, xy=被指点, xytext=文字位置, arrowprops={…});text(x,y,s) 无箭头。 |
| 图例 | 绘图时写 label;plt.legend(loc=…, bbox_to_anchor=…, ncol=…);不要遮挡数据。 |
| 柱状图 | bar 离散类别;barh 类别名长;bottom 堆积;x±width/2 并列;xticks 对齐类别中心。 |
| 直方图 | hist 连续变量分布;bins 决定分箱;histtype: bar/barstacked/step/stepfilled。 |
| 饼图 | pie 少量类别占比;autopct 显示比例;startangle 起始角;axis(“equal”) 变圆;类别多不用。 |
| 箱线图 | boxplot 看中位数、Q1/Q3、IQR、须、异常点;默认 whis=1.5。 |
| colormap | Sequential 连续;Diverging 正负/中点;Qualitative 类别;有颜色映射加 colorbar。 |
| 多图 | subplot(行,列,编号),编号从1开始;fig, axes = plt.subplots(r,c) 更适合复杂布局。 |
| 必防错误 | 不要 plt=plt.plot(…); x/y 长度一致;legend 需要 label;中文和负号要设置;hist/bar 不混。 |
最后复习建议:先背概念区别和图表选择,再练 8–10 个常用代码模板,最后做代码阅读题,重点检查参数含义、图例/标签、坐标范围、数据类型是否匹配。
第 5 章 探索式数据分析 EDA#
内容来源:原文件内容。 课程 PPT《3-探索式数据分析-20260420.pdf》与 2026-04-20 课堂转录。
0. 资料定位与转录修正#
| 材料位置 | 主要内容 | 复习用途 |
|---|---|---|
| PPT p.3-p.5;转录约 34:02-36<47>47> | EDA 含义、目标;EDA 与 CDA 对比;按变量个数组织内容。 | 概念题、简答题开头标准表述。 |
| PPT p.7-p.18;转录约 38:05-48<47>47> | 一个变量:描述性统计、箱线图/小提琴图、基尼系数、分布图、PDF/CDF/CCDF。 | 单变量分析题和图表选择题。 |
| PPT p.19-p.31;转录约 49:35-1:09<37>37> | 正态分布检验:数值法、图示法、统计检验法;非正态变换。 | 统计检验前置判断、代码题。 |
| PPT p.33-p.50;转录约 1:10:17-1:26<06>06> | 参数/非参数检验;t 检验、ANOVA、卡方检验、K-S 检验。 | 检验方法选择题、p 值解释。 |
| PPT p.51-p.58;转录约 1:26:50-1:30<59>59> | 两个变量:散点图、相关系数、Pearson/Spearman、相关系数局限。 | 相关分析、散点图解读。 |
| PPT p.59-p.75;转录约 1:30:59-1:50<24>24> | 三个及以上变量:气泡图、相关矩阵/热力图、因子分析步骤与例子。 | 多变量降维、因子命名、KMO/Bartlett/loading。 |
| PPT p.76-p.86;课堂未详细展开 | PCA 概念、协方差/相关矩阵、特征值、解释率、loading、PCA 与因子分析区别。 | PPT 中出现,期末可能作为概念或辨析题;Python Notebook 未提供。 |
| 转录约 03:13-32<04>04> | Matplotlib 练习讲评:柱状图、饼图、多折线、分组柱、时间趋势、标签重叠、颜色一致、对数坐标。 | 代码题和可视化应用题的常见坑。 |
| 转录原文可能错误 | 根据上下文修正 | 依据 |
|---|---|---|
| CIU read CHEEN / 读 CHEEN | CSV 读取,通常为 pd.read_csv() | 学生展示数据读取代码。 |
| 体检验 | t 检验 | PPT p.35-p.41 均为 t 检验。 |
| 风度 / 偏入 | 峰度 / 偏度 | 正态性数值法。 |
| C点 / CCBF / BDF | CDF / CCDF / PDF | 分布图讲解。 |
| AD/AB 检验 | Anderson-Darling 检验(AD 检验) | PPT p.29-p.30。 |
| SBTI/SDPI | 可能为 MBTI(可能为转录误差) | 老师举“人格测试背后可能使用因子分析”的例子。 |
| logo 的曲线 / 路由曲线 | Lorenz 曲线(洛伦兹曲线) | 基尼系数讲解。 |
1. 本讲/本章知识框架#
本章主线是:先理解数据,再选择图表和统计方法;先探索结构,再考虑验证假设或建模。
-
- EDA 总论:定义、目标、与 CDA 的区别。
-
- 一个变量的分析:描述性统计 → 分布可视化 → 正态性检验 → 多组样本检验。
-
- 两个变量的分析:散点图观察关系 → 相关系数量化关系 → 检查相关系数的适用条件与局限。
-
- 三个及以上变量的分析:用气泡图/热力图展示有限变量;用相关矩阵、散点图矩阵、因子分析、PCA 等进行多变量结构识别和降维。
-
- Python 实现:pandas/numpy 做统计,matplotlib/seaborn 做图,scipy/statsmodels/sklearn 做检验和降维。 | 层级 | 问题 | 主要方法 | 输出结果 | 与下一步关系 | | --- | --- | --- | --- | --- | | 总论 | 数据“长什么样”? | EDA:定量方法 + 可视化工具 | 变量特征、异常值、潜在结构、重要变量 | 为 CDA、机器学习、回归建模提供假设和变量选择。 | | 单变量 | 一个变量的中心、离散、形态如何? | describe、均值/中位数、箱线图、直方图、PDF/CDF/CCDF、正态检验 | 分布形态、异常值、是否近似正态 | 决定是否做参数检验,是否需要 log/sqrt 变换。 | | 多组同一变量 | 不同组的均值/分布是否不同? | t 检验、ANOVA、卡方检验、K-S 检验 | 统计量、p 值、是否拒绝 H0 | 为“是否有显著差异”提供证据。 | | 双变量 | 两个变量是否相关?关系形态如何? | 散点图、相关系数 Pearson/Spearman/Kendall | 相关方向、强度、线性/非线性关系 | 为变量筛选、建模关系假设提供依据。 | | 多变量 | 多个变量能否降维或分组? | 气泡图、热力图、散点图矩阵、因子分析、PCA | 潜在因子、主成分、变量簇、载荷/解释率 | 减少变量数量,构造综合指标或机器学习输入。 |
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| 探索式数据分析 | Exploratory Data Analysis, EDA | 用定量方法和可视化工具分析变量规律、趋势、隐含结构、离散和异常情况。 | 拿到数据后、建模前、没有明确假设时。 | 不是最终验证;它生成假设。 | “EDA 的含义和目标是什么?” |
| 验证式数据分析 | Confirmatory Data Analysis, CDA | 从假设出发,通过统计模型或检验验证假设。 | 已有理论假设、需要检验 H0 时。 | 与 EDA 的起点相反:CDA 先假设,EDA 先探索。 | “比较 EDA 与 CDA。” |
| 描述性统计 | Descriptive statistics | 用数值概括一个变量的中心、离散和偏离程度。 | 单变量概览、异常初筛。 | 均值易受极端值影响;中位数更稳健。 | “描述性统计主要关注哪些方面?” |
| 变异系数 | Coefficient of Variation, CV | 标准差除以均值,用于消除量纲或均值规模影响后的相对离散程度。 | 比较不同量纲或均值差异较大的变量波动。 | 均值接近 0 时 CV 不稳定。 | “为什么标准差有时要除以均值?” |
| z 分数 | z-score | 某个样本值距离均值多少个标准差:z=(x-μ)/σ。 | 标准化、异常值识别、不同量纲变量比较。 | 一列数据会得到一列 z 分数,不是一个总指标。 | “z 分数能用在什么场景?” |
| 箱线图 | Box plot | 显示 Q1、中位数、Q3、IQR、须和异常点。 | 查看分布、离散、异常值;组间比较。 | 须通常到 Q1-1.5IQR 和 Q3+1.5IQR 内的边界。 | “箱线图如何识别异常值?” |
| 小提琴图 | Violin plot | 在箱线图基础上叠加密度形状。 | 需要同时看分位数和分布形态。 | 宽度表示密度,不是类别大小。 | “小提琴图相对箱线图多了什么信息?” |
| 基尼系数 | Gini index | 衡量分布不均衡程度,0 越均衡,1 越不均衡。 | 收入分配、资源/发文/引用等集中度分析。 | 宏观经济阈值是经验规则,不应机械套用到所有场景。 | “如何用 Lorenz 曲线解释基尼系数?” |
| 直方图 | Histogram | 把连续变量按数值区间分箱后统计频数或密度。 | 连续变量分布。 | 不同于柱状图:直方图区间连续、柱子通常无间隔。 | “柱状图和直方图区别?” |
| 密度分布 | Probability Density Function, PDF | 展示变量取值的相对集中程度。 | 连续变量分布形态。 | 密度不是概率;区间面积才对应概率。 | “PDF 高的地方意味着什么?” |
| 累积分布 | Cumulative Distribution Function, CDF | F(x)=P(X≤x),表示不超过 x 的比例。 | 极度不均匀分布、需要看累积比例时。 | CDF 上升快的位置对应原分布样本多。 | “什么时候用 CDF?” |
| 互补累积分布 | Complementary CDF, CCDF | 1-F(x)=P(X>x),强调超过某阈值的比例。 | 长尾/重尾数据、引用数/点赞数/流量等。 | 读图方向常从右侧尾部理解。 | “CCDF 如何解释?” |
| 偏度 | Skewness | 衡量分布不对称性;正值通常右偏,负值通常左偏。 | 正态性初判、分布形态判断。 | 偏态看尾巴方向,不是看峰值在哪边。 | “右偏时均值、中位数、众数关系?” |
| 峰度 | Kurtosis | 衡量分布尖峭/尾部厚度。 | 正态性初判、识别重尾。 | 课程经验阈值:峰度绝对值≤10,偏度绝对值≤3。 | “数值法如何判断近似正态?” |
| Shapiro-Wilk 检验 | Shapiro-Wilk test | 正态性统计检验,H0:样本来自正态分布。 | 小样本正态性检验。 | p<α 拒绝正态假设;p 大不是“证明正态”。 | “SW 检验 p 值如何解释?” |
| Anderson-Darling 检验 | Anderson-Darling test | 可检验样本是否符合指定分布,如 norm、expon、logistic。 | 正态或其他理论分布检验。 | scipy.anderson 主要比较 statistic 与 critical values。 | “AD 检验与 SW 检验差异?” |
| 参数检验 | Parametric test | 假定总体服从已知分布,并检验总体参数。 | 变量近似正态、连续数据。 | 效能较高但前提更强。 | “何时使用参数检验?” |
| 非参数检验 | Non-parametric test | 不严格要求总体分布形式。 | 非正态、分类/离散数据、分布未知。 | 适用范围广但检验效能较低。 | “参数与非参数检验区别?” |
| t 检验 | t-test | 比较均值差异的参数检验。 | 一组 vs 常数、配对两组、独立两组。 | 关注均值,不是方差或相关性。 | “三类 t 检验分别用于什么场景?” |
| 方差分析 | ANOVA / F test | 比较多个正态总体均值是否相等。 | 三组及以上均值比较。 | 显著只说明至少两组不同,不直接告诉哪两组。 | “ANOVA 后为什么还要 Tukey?” |
| 卡方检验 | Chi-square test | 基于频数的分类数据检验。 | 分类变量比例/关系检验。 | 不是用于连续均值比较。 | “性别与是否看直播是否有关用什么检验?” |
| K-S 检验 | Kolmogorov-Smirnov test | 比较样本分布与理论分布或两样本分布差异。 | 分布一致性检验。 | 课程写法为 stats.kstest;两样本常用 ks_2samp。 | “K-S 检验能回答什么问题?” |
| 相关系数 | Correlation coefficient | 用一个数描述两个变量相关方向与强度。 | 双变量关系量化。 | 相关不等于因果;同一相关系数可对应不同形态。 | “为什么不能只看相关系数?” |
| Pearson 相关 | Pearson correlation | 线性相关系数,适用于连续、近似正态、线性关系。 | 两个连续变量线性关系。 | 不能捕捉典型非线性关系。 | “Pearson 的适用条件?” |
| Spearman 相关 | Spearman rank correlation | 基于秩的相关,适合单调关系或非正态数据。 | 有序变量、非正态、单调非线性关系。 | 不是专门测线性,而是秩单调关系。 | “Pearson 不适合时可用什么?” |
| 气泡图 | Bubble plot | 散点图上用点大小/颜色编码第三个变量。 | 三个变量关系展示。 | 大小映射要加图例,否则难解释。 | “三个连续变量如何可视化?” |
| 因子分析 | Factor analysis | 从多个观测变量中提取少数潜在因子,解释共同结构。 | 问卷、心理量表、变量降维和因子命名。 | 先检验 KMO/Bartlett;因子需要解释和命名。 | “因子分析三步是什么?” |
| 主成分分析 | Principal Component Analysis, PCA | 通过线性变换提取解释方差最大的正交主成分。 | 降维、构造综合指标、后续建模输入。 | PCA 找最大方差方向;因子分析更关注共同潜在因子。 | “PCA 与因子分析区别?” |
3. 重点知识详解#
3.1 EDA 的定义、目标与 CDA 区别#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | EDA 是使用定量方法和可视化工具,对数据集中变量的规律、趋势、隐含结构、离散情况、异常情况等进行分析。CDA 是从假设出发并用统计模型/检验验证假设。 |
| 直观理解 | EDA 像“看地图”:先认识数据;CDA 像“验证路线”:已有理论假设后检验是否成立。 |
| PPT 中对应内容 | PPT p.3 给出 EDA 含义和目标;p.4 对比 EDA 与 CDA。 |
| 老师课堂强调 | 老师强调 EDA 依靠两个东西:量化方法和可视化工具;EDA 没有预先假设,目标之一是生成假设。CDA 从假设开始,通常测试零假设。 |
| 典型例子 | 拿到一个包含 100 个变量的表,先通过 EDA 找出关键变量、异常值和变量结构,再用于机器学习建模。 |
| 可能考点 | 简答题:“说明 EDA 的目标”;辨析题:“EDA 与 CDA 的区别”。标准表述:EDA 不以预设假设为起点,主要生成假设;CDA 以假设为起点,主要验证假设。 |
| 常见错误 | 把 EDA 写成“统计检验”是不完整的;忽略可视化也是错误的。 |
3.2 描述性统计:中心、离散、偏离#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 描述性统计用数值概括变量,包括中心位置(均值、中位数、众数)、发散程度(极差、方差、标准差、变异系数)和偏差程度(z 分数)。 |
| 直观理解 | 先用少数指标给变量画像:一般水平在哪里、波动多大、某个样本是否异常。 |
| PPT 中对应内容 | PPT p.8-p.9 给出 numpy/pandas 代码和指标分类。 |
| 老师课堂强调 | 老师强调:z 分数是一堆数变成一堆数,每个样本都有自己的 z 分数;不是像方差那样一列数据只算出一个数。 |
| 典型例子 | 身高数据:每个人身高减去全班平均身高,再除以全班标准差,得到每个人的 z 分数。 |
| 可能考点 | 代码题:np.mean、np.median、np.var、np.std、np.ptp、df.describe;概念题:CV 为什么要除以 mean。 |
| 常见错误 | 均值受极端值影响;np.var/np.std 默认总体方差/标准差(ddof=0),与样本统计量可能不同;均值接近 0 时 CV 失真。 |
3.3 箱线图、小提琴图与异常值#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 箱线图展示 Q1、中位数、Q3、IQR、上下须和异常点;小提琴图在此基础上展示密度形态。 |
| 直观理解 | 箱线图适合快速比较组间分布和异常值;小提琴图可以看分布是否多峰、偏态。 |
| PPT 中对应内容 | PPT p.10 展示箱形图、小提琴图以及 1.5IQR 与正态分布示意。 |
| 老师课堂强调 | 老师解释 1.5IQR 与近似 2.698σ 的位置相关,接近常说的 3σ 异常范围。 |
| 典型例子 | 不同航空公司延误比例分布:箱线图看中位数和异常点,小提琴图看延误比例在哪些区间更集中。 |
| 可能考点 | 可能问:箱线图的五数概括;异常值判定;小提琴图和箱线图区别。 |
| 常见错误 | 把小提琴图的宽度理解为“类别样本总量”不准确;它主要反映该位置附近的密度。 |
3.4 基尼系数与 Lorenz 曲线#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 基尼系数衡量分布不均衡程度,取值常在 0-1,越接近 0 越均衡,越接近 1 越不均衡。 |
| 直观理解 | 先把收入或资源从小到大排序,画累计人数比例与累计收入/资源比例;实际曲线偏离 45° 绝对平等线越多,越不均衡。 |
| PPT 中对应内容 | PPT p.11 给出宏观经济领域的基尼系数解释。 |
| 老师课堂强调 | 老师强调:宏观经济中的 0.2/0.3/0.4/0.5 只是该领域经验划分;在其他场景不要机械套用。算法直观上是 A 面积除以整个三角形面积。 |
| 典型例子 | 一个班 60 人,若每人收入相同,Lorenz 曲线与 45° 线重合,Gini=0;若 1 人拿走所有收入,其余为 0,Gini 接近 1。 |
| 可能考点 | 可能问:为什么 Gini 能衡量均衡性;如何读 Lorenz 曲线。 |
| 常见错误 | 排序方向不能错;不是对原始顺序直接累加;不要把宏观经济阈值泛化到论文引用、发文量等其他数据。 |
3.5 分布图:柱状图、直方图、PDF、CDF、CCDF#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 表格/柱状图用于类别或离散取值;直方图用于连续变量分箱;PDF 表示密度;CDF 表示不超过某值的累计比例;CCDF 表示超过某值的比例。 |
| 直观理解 | 同一个变量的分布可以从“频数”“密度”“累计比例”“尾部比例”多角度观察。 |
| PPT 中对应内容 | PPT p.14-p.18 系统列出表格/柱状图、直方图、密度分布、CDF/CCDF。 |
| 老师课堂强调 | 老师强调:CDF 上升快的位置对应原始密度中样本最多的位置;当分布极度悬殊、长尾明显时,CDF/CCDF 或对数坐标比普通 PDF/柱状图更有用。 |
| 典型例子 | 引用次数、点赞数、评论数常呈长尾分布。普通柱状图可能大量堆在左侧,此时可尝试 log-log 图或 CCDF。 |
| 可能考点 | 选择题:什么时候画柱状图、直方图、CDF/CCDF;简答题:CDF 与 PDF 如何相互印证。 |
| 常见错误 | 柱状图和直方图混用;长尾数据不取对数导致图形不可读;CCDF 读成 P(X≤x) 是错误的,CCDF 是 P(X>x)。 |
3.6 正态分布检验:数值法、图示法、统计检验法#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 正态性可以用三类方法判断:数值法(偏度、峰度)、图示法(直方图、PP/QQ 图)、统计检验法(Shapiro-Wilk、Anderson-Darling)。 |
| 直观理解 | 先粗看形状,再用统计检验确认;若不正态,可尝试 log、sqrt 等变换。 |
| PPT 中对应内容 | PPT p.19-p.31 给出三类方法和 Python 代码。 |
| 老师课堂强调 | 老师强调:直方图法简单但不可靠;QQ 图要理解横轴理论分位数、纵轴样本分位数;SW 检验的 H0 是正态,p<α 才拒绝;log-normal 指取对数后近似正态。 |
| 典型例子 | 随机生成 100 个近似正态数据,用 qqplot(data, line=“s”) 查看散点是否接近直线;用 shapiro(data) 返回统计量和 p 值。 |
| 可能考点 | 代码题:写 SW/AD 检验代码并解释 p 值;图形题:根据 QQ 图判断左偏、右偏、长尾。 |
| 常见错误 | 把 p 大理解成“证明正态”;只靠肉眼看直方图;QQ 图左偏/右偏方向记反;数据有 0 或负数时直接 log 导致报错或 NaN。 |
3.7 参数检验与非参数检验#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 参数检验假定总体来自已知分布并检验总体参数;非参数检验对总体分布不作严格规定。 |
| 直观理解 | 变量近似正态且连续时优先考虑参数检验;分布未知、非正态或分类数据时考虑非参数方法。 |
| PPT 中对应内容 | PPT p.33-p.34 给出参数/非参数检验对比表。 |
| 老师课堂强调 | 老师强调:正态性测试可以作为选择参数检验的前置判断;t 检验和 F 检验是参数检验,卡方检验和 K-S 检验是常见非参数检验。 |
| 典型例子 | 身高或寿命等连续近似正态变量可用 t 检验;性别与是否看直播这种分类变量关系用卡方检验。 |
| 可能考点 | 可能问:参数/非参数区别;某数据应选哪类检验。 |
| 常见错误 | 把“非参数”理解为没有统计量;忽略数据类型;样本不独立却用独立样本检验。 |
3.8 t 检验、ANOVA、卡方检验、K-S 检验#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | t 检验比较均值;ANOVA 比较三组及以上均值;卡方检验处理分类变量频数;K-S 检验比较分布差异。 |
| 直观理解 | 根据“几组数据、是否配对、变量类型、检验目标”选择方法。 |
| PPT 中对应内容 | PPT p.35-p.50 给出 t 检验、F 检验、卡方检验和 K-S 检验定义与代码。 |
| 老师课堂强调 | 老师强调:单样本 t 是一组数据与常数比较;配对样本必须样本一一对应且数量相等;独立样本不要求数量相等;ANOVA 显著后只说明至少两组不同,需 Tukey 进一步判断哪两组不同。 |
| 典型例子 | 点火器寿命 vs 1200 用单样本 t;同 15 人两种血压计测量值用配对 t;两种蓄电池续航用独立 t;三名射击选手成绩用单因素 ANOVA。 |
| 可能考点 | 代码题:stats.ttest_1samp/ttest_rel/ttest_ind/f_oneway;解释 statistic 正负与 p 值。 |
| 常见错误 | 配对与独立搞混;ANOVA 后直接断定“谁最好”但未做事后检验;把卡方用于连续均值。 |
3.9 两个变量:散点图与相关系数#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 两个变量关系先用散点图观察,再用相关系数量化。Pearson 适合连续、近似正态、线性关系;Spearman/Kendall 更适合秩相关或非正态情形。 |
| 直观理解 | 散点图负责看“形状”,相关系数负责给“数字”。两者必须结合。 |
| PPT 中对应内容 | PPT p.51-p.58 展示散点图、相关系数、Pearson/Spearman 和相关系数局限。 |
| 老师课堂强调 | 老师明确强调:千万不要拿到 X、Y 后只算相关系数;相关系数相同的图,背后的关系可能完全不同;散点图虽然简单,但一定要画。 |
| 典型例子 | 温度与饮料销量可能不是线性:太冷没人买,太热也没人出门,中间温度销量最高,Pearson 可能无法捕捉。 |
| 可能考点 | 概念题:Pearson 的三个条件;分析题:为什么相关系数不是万能的。 |
| 常见错误 | 相关当因果;非线性关系仍用 Pearson 下结论;没有画散点图就解释相关系数。 |
3.10 三个及以上变量:相关矩阵、热力图、气泡图#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 三个变量可用气泡图把第三变量映射为点大小/颜色;多个变量可用相关矩阵、热力图、散点图矩阵两两观察。 |
| 直观理解 | 多变量难以一次完整可视化,因此常拆成两两关系或进行降维。 |
| PPT 中对应内容 | PPT p.59-p.64 展示气泡图、热力图、散点图矩阵等。 |
| 老师课堂强调 | 老师强调热力图读法:颜色深浅表示相关强度,椭圆越扁相关越强;若某变量方向与其他指标相反,建模前可能需要取相反数或倒数;高度相关的一组变量后续建模不必全部保留。 |
| 典型例子 | 多个文献影响力指标之间高度相关时,机器学习建模可从其中选择代表变量,避免冗余。 |
| 可能考点 | 可能问:三个变量可视化方式;相关矩阵如何帮助变量筛选。 |
| 常见错误 | 热力图颜色方向不看图例;把高相关变量全部塞进模型;忽略变量方向一致性。 |
3.11 因子分析:目的、步骤与命名#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | 因子分析通过研究多个观测变量的内部依赖关系,用少数潜在因子表示原始变量的共同结构,目标是在信息损失尽量小的前提下降维。 |
| 直观理解 | 把相关性强的变量“打包”:例如九科成绩可打包为理科能力、文科能力、语言能力。 |
| PPT 中对应内容 | PPT p.65-p.75 给出定义、学科成绩例子、碎石图、loading、KMO/Bartlett、bfi2010 大五人格数据。 |
| 老师课堂强调 | 老师明确说“因子分析三步是重点”:第一看适不适合做(KMO、Bartlett);第二决定提取几个因子并看方差解释率;第三分析 loading 并给因子命名。 |
| 典型例子 | 高中九科成绩例子:数学、物理、化学、生物在因子 1 上载荷高,可命名为理科能力;政治、历史、地理在因子 2 上高,可命名为文科能力;语文、英语在因子 3 上高,可命名为语言能力。地理兼具一定理科特征。 |
| 可能考点 | 简答题:因子分析步骤;应用题:根据 loading 表给因子命名;代码题:KMO/Bartlett 和 loadings。 |
| 常见错误 | 不先做适用性检验;只看特征值不看解释率;因子命名脱离高载荷变量;把因子分析与 PCA 完全混同。 |
3.12 PCA:PPT 中出现但课堂未展开的降维方法#
| 维度 | 整理内容 |
|---|---|
| 概念定义 | PCA 通过线性组合得到若干正交主成分,使前几个主成分尽可能解释原始变量的变异。 |
| 直观理解 | PCA 找的是“最大方差方向”;适合把多个相关变量压缩为少数综合指标。 |
| PPT 中对应内容 | PPT p.76-p.86 给出 PCA 定义、协方差/相关矩阵例子、解释率、主成分选择和 loading。课堂转录显示老师说后面 PCA 部分未详细讲解,材料中未提供 Jupyter Notebook。 |
| 老师课堂强调 | 老师未展开讲授。复习时应掌握 PPT 级别概念:若变量单位不同或方差差异大,应使用相关矩阵/标准化;主成分数量看特征值、碎石图、累计解释率。 |
| 典型例子 | 英语修课成绩和英文检定成绩:用协方差矩阵可能被量纲/方差大的变量主导;用相关矩阵后两个变量权重相同,第一主成分可解释约 91% 变异。 |
| 可能考点 | 可能问:PCA 与因子分析区别;为什么要标准化;如何根据解释率选主成分。 |
| 常见错误 | 未标准化导致量纲大的变量支配 PCA;把主成分解释为真实潜在心理因子;累计解释率过低仍强行降维。 |
4. Python 实现与代码模板#
以下模板分为“PPT/课堂出现的代码思想”和“根据课程内容整理的通用模板”。实际考试或作业应根据变量名替换 df、x、y、group 等。
4.1 数据读取与快速检查#
import pandas as pdimport numpy as np
# 输入:CSV/Excel 文件路径;输出:DataFrame# 用途:读取数据并进行基础检查path = "data.csv"df = pd.read_csv(path) # Excel 可用 pd.read_excel("data.xlsx")
print(df.head()) # 前 5 行print(df.info()) # 字段类型和缺失情况print(df.describe()) # 数值列描述性统计print(df.isna().sum()) # 各列缺失值数量
# 易错点:# 1. 中文路径/编码问题:可尝试 encoding="utf-8-sig" 或 encoding="gbk"# 2. 数字列被读成 object:用 pd.to_numeric(df[col], errors="coerce") 转换4.2 描述性统计与 z 分数#
import numpy as np
x = df["value"].dropna()
summary = { "min": x.min(), "max": x.max(), "mean": x.mean(), "median": x.median(), "mode": x.mode().iloc[0] if not x.mode().empty else np.nan, "range": np.ptp(x), "var": np.var(x), # numpy 默认 ddof=0;样本方差可用 x.var(ddof=1) "std": np.std(x), "cv": np.std(x) / np.mean(x), "q1": x.quantile(0.25), "q3": x.quantile(0.75),}print(summary)
# z 分数:一列输入 -> 一列输出z = (x - x.mean()) / x.std(ddof=0)outliers = df.loc[z.abs() > 3]
# 易错点:均值接近 0 时 CV 不稳定;z 分数不是一个总数。4.3 类别分布:频数表、柱状图、饼图#
import matplotlib.pyplot as plt
# 输入:分类变量列;输出:频数/比例与图counts = df["category"].value_counts(dropna=False)props = df["category"].value_counts(normalize=True, dropna=False)print(pd.DataFrame({"count": counts, "proportion": props}))
# 柱状图:适合类别变量ax = counts.plot(kind="bar", figsize=(7, 4))ax.set_xlabel("Category")ax.set_ylabel("Frequency")ax.set_title("Distribution of category")for i, v in enumerate(counts.values): ax.text(i, v, str(v), ha="center", va="bottom", fontsize=8)plt.xticks(rotation=45, ha="right")plt.tight_layout()plt.show()
# 饼图:类别较少且想展示占比时使用;类别多时不推荐props.plot(kind="pie", autopct="%.1f%%", figsize=(5, 5))plt.ylabel("")plt.tight_layout()plt.show()
# 易错点:类别太多时饼图可读性差;标签重叠时需旋转或调整布局。4.4 连续变量分布:直方图、KDE、CDF、CCDF、对数坐标#
import numpy as npimport matplotlib.pyplot as pltimport seaborn as sns
x = df["value"].dropna()
# 直方图 + KDE:观察连续变量分布sns.histplot(x, bins=30, kde=True)plt.xlabel("value")plt.ylabel("Frequency")plt.title("Histogram and KDE")plt.tight_layout()plt.show()
# CDF:F(x)=P(X<=x)x_sorted = np.sort(x)cdf = np.arange(1, len(x_sorted) + 1) / len(x_sorted)plt.plot(x_sorted, cdf)plt.xlabel("x")plt.ylabel("CDF")plt.title("Cumulative distribution")plt.tight_layout()plt.show()
# CCDF:P(X>x),适合长尾/极度悬殊分布ccdf = 1 - cdfplt.plot(x_sorted, ccdf)plt.xscale("log") # x 必须为正;若有 0,可用 x+1 或先过滤plt.yscale("log")plt.xlabel("x (log scale)")plt.ylabel("CCDF (log scale)")plt.title("Complementary CDF")plt.tight_layout()plt.show()
# 易错点:log 不能直接作用于 0 或负数;CDF 与 CCDF 含义不要写反。4.5 正态性检验:偏度/峰度、QQ 图、SW、AD#
import pandas as pdimport scipy.stats as statsfrom statsmodels.graphics.gofplots import qqplotimport matplotlib.pyplot as plt
x = df["value"].dropna()
# 数值法:偏度、峰度(课程经验阈值:|偏度|<=3,|峰度|<=10)print("skewness:", x.skew())print("kurtosis:", x.kurt()) # pandas 默认是 Fisher kurtosis(正态约为 0)
# 图示法:QQ 图qqplot(x, line="s")plt.title("Q-Q plot")plt.tight_layout()plt.show()
# Shapiro-Wilk 检验:H0 = 数据来自正态分布stat, p = stats.shapiro(x)alpha = 0.05print(f"SW statistic={stat:.3f}, p={p:.3f}")print("fail to reject H0: approximately normal" if p > alpha else "reject H0: not normal")
# Anderson-Darling 检验:比较 statistic 与 critical valuesres = stats.anderson(x, dist="norm")print("AD statistic:", res.statistic)for sl, cv in zip(res.significance_level, res.critical_values): print(f"significance={sl}%, critical={cv}, normal={res.statistic < cv}")
# 非正态可尝试变换:注意 x 必须满足取值条件x_log = np.log1p(x[x >= 0]) # log(1+x),适合非负且含 0 的变量4.6 t 检验、ANOVA、Tukey、卡方、K-S#
import numpy as npfrom scipy import statsfrom statsmodels.stats.multicomp import MultiComparison
# 1. 单样本 t 检验:一组数据 vs 常数sample = np.array([809, 1250, 689, 1541, 995, 1234, 1024, 920, 777, 2510])res = stats.ttest_1samp(sample, popmean=1200)print(res.statistic, res.pvalue)
# 2. 配对样本 t 检验:两组一一对应,长度必须相等before = np.array([68, 85, 123])after = np.array([60, 88, 132])res = stats.ttest_rel(before, after)print(res.statistic, res.pvalue)
# 3. 独立样本 t 检验:两组相互独立,长度可以不同A = np.array([5.5, 5.6, 6.3, 4.6])B = np.array([3.8, 4.3, 4.2, 4.0, 4.9])res = stats.ttest_ind(A, B, equal_var=True) # 方差不齐时可设 equal_var=Falseprint(res.statistic, res.pvalue)
# 4. 单因素 ANOVA:三组及以上均值比较;显著后只说明至少两组不同f, p = stats.f_oneway(A, B, np.array([6.0, 6.1, 5.8]))print(f, p)
# Tukey 事后检验:判断具体哪两组不同(根据课程内容整理的通用模板)values = np.r_[A, B]groups = ["A"] * len(A) + ["B"] * len(B)mc = MultiComparison(values, groups)print(mc.tukeyhsd())
# 5. 卡方检验:分类数据频数# 单组优度检验:观测频数 vs 期望频数obs = np.array([30, 50, 20])exp = np.array([33.3, 33.3, 33.4])print(stats.chisquare(f_obs=obs, f_exp=exp))
# 交叉表卡方检验:两个分类变量是否有关contingency = pd.crosstab(df["gender"], df["watch_live"])chi2, p, dof, expected = stats.chi2_contingency(contingency)print(chi2, p, dof)
# 6. K-S 检验:样本是否符合指定理论分布;两样本比较常用 ks_2sampx = df["value"].dropna()print(stats.kstest(x, "norm", args=(x.mean(), x.std(ddof=1))))# print(stats.ks_2samp(sample1, sample2)) # 补充理解:两样本分布比较4.7 两变量关系:散点图、相关系数、相关矩阵#
import seaborn as snsimport matplotlib.pyplot as pltfrom scipy.stats import pearsonr, spearmanr
x = df["x"].dropna()y = df.loc[x.index, "y"]
# 散点图:老师强调必须先画图看结构sns.scatterplot(data=df, x="x", y="y")plt.title("Scatter plot of x and y")plt.tight_layout()plt.show()
# 相关系数print("Pearson:", pearsonr(x, y)) # 连续、正态、线性print("Spearman:", spearmanr(x, y)) # 秩相关,适合单调关系/非正态
# 多变量相关矩阵 + 热力图num_cols = ["x1", "x2", "x3", "x4"]corr = df[num_cols].corr(method="pearson")sns.heatmap(corr, annot=True, fmt=".2f", square=True)plt.title("Correlation matrix")plt.tight_layout()plt.show()
# 易错点:相关系数相同不代表关系形态相同;相关不等于因果。4.8 多变量图:气泡图、散点图矩阵#
# 气泡图:x、y 两个坐标,size 或 hue 表示第三个变量sns.scatterplot(data=df, x="height", y="weight", size="lung_capacity", hue="group", sizes=(20, 300), alpha=0.7)plt.title("Bubble plot")plt.tight_layout()plt.show()
# 散点图矩阵:多个数值变量两两关系sns.pairplot(df[["x1", "x2", "x3", "x4"]].dropna())plt.show()
# 易错点:变量多时 pairplot 很占空间;报告中应筛选关键变量。4.9 因子分析模板(根据课程内容整理的通用模板)#
PPT p.75 仅说明“参见 Jupyter Notebook 文档”,材料中未提供完整 Notebook。以下是按照课堂三步法整理的通用模板,考试主要掌握流程和输出解释。
# 需要安装:pip install factor_analyzerimport pandas as pdfrom factor_analyzer import FactorAnalyzerfrom factor_analyzer.factor_analyzer import calculate_kmo, calculate_bartlett_sphericity
cols = ["A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3"] # 替换为题目变量X = df[cols].dropna()
# Step 1: 适用性检验kmo_all, kmo_model = calculate_kmo(X)chi_square_value, p_value = calculate_bartlett_sphericity(X)print("KMO:", kmo_model) # >0.8 非常适合;0.7-0.8 较适合;<0.6/0.5 不适合print("Bartlett p:", p_value) # p<0.05 适合
# Step 2: 决定因子个数:看特征值、碎石图、累计解释率fa0 = FactorAnalyzer(rotation=None)fa0.fit(X)ev, v = fa0.get_eigenvalues()print(ev) # 经验:特征值 > 1 的因子可保留
# Step 3: 拟合因子模型并解释 loadingn_factors = 5fa = FactorAnalyzer(n_factors=n_factors, rotation="varimax")fa.fit(X)loadings = pd.DataFrame(fa.loadings_, index=cols, columns=[f"F{i+1}" for i in range(n_factors)])print(loadings.round(3)) # loading 绝对值 > 0.3 常作为解释参考print(fa.get_factor_variance()) # 方差解释率与累计解释率
# 解释要点:看每个因子在哪些变量上 loading 高,再结合变量含义命名因子。4.10 PCA 模板(PPT 出现,课堂未展开)#
from sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAimport pandas as pd
cols = ["x1", "x2", "x3", "x4"]X = df[cols].dropna()
# 单位不同或方差差异大时先标准化X_std = StandardScaler().fit_transform(X)
pca = PCA(n_components=None)Z = pca.fit_transform(X_std)
explained = pd.Series(pca.explained_variance_ratio_, index=[f"PC{i+1}" for i in range(len(cols))])print("explained ratio:")print(explained)print("cumulative explained ratio:")print(explained.cumsum())
loadings = pd.DataFrame(pca.components_.T, index=cols, columns=[f"PC{i+1}" for i in range(len(cols))])print(loadings.round(3))
# 选择主成分:常看特征值>1、碎石图、累计解释率(如 >=0.7 或更高)。4.11 Matplotlib 练习中反复出现的可视化模板#
import matplotlib.pyplot as pltimport numpy as np
# A. 分组柱状图:设置 width 和 x 偏移,避免柱子重叠labels = ["Jan", "Feb", "Mar", "Apr"]series1 = [10, 14, 12, 18]series2 = [8, 11, 13, 16]x = np.arange(len(labels))width = 0.35fig, ax = plt.subplots(figsize=(7, 4))ax.bar(x - width/2, series1, width, label="A")ax.bar(x + width/2, series2, width, label="B")ax.set_xticks(x)ax.set_xticklabels(labels)ax.set_ylabel("Value")ax.legend()plt.tight_layout()plt.show()
# B. 时间序列:按年统计,并补齐缺失年份为 0,避免折线断裂或结构不好看yearly = df.groupby("year")["paper_id"].nunique()full_years = range(yearly.index.min(), yearly.index.max() + 1)yearly = yearly.reindex(full_years, fill_value=0)yearly.plot(marker="o")plt.xlabel("Year")plt.ylabel("Number of papers")plt.tight_layout()plt.show()
# C. 多条折线:注意重合线可能被后一条完全盖住;必要时检查数据是否相同for col in ["product_A", "product_B", "product_C"]: plt.plot(df["month"], df[col], marker="o", label=col)plt.legend()plt.xticks(rotation=45)plt.tight_layout()plt.show()
# D. 保存图片plt.savefig("figure.png", dpi=300, bbox_inches="tight")5. 图表/方法选择指南#
| 遇到的问题/数据 | 优先方法 | Python 常用函数 | 输出怎么解释 | 易错提醒 |
|---|---|---|---|---|
| 一个分类变量的分布 | 频数表、柱状图;类别少可用饼图 | value_counts(), plot(kind=“bar”), pie() | 哪类最多、比例多少、是否极不均衡 | 类别多时饼图不清楚;标签要可读。 |
| 一个连续变量的分布 | describe、直方图、KDE、箱线图/小提琴图 | describe(), sns.histplot(), sns.boxplot() | 中心、离散、偏态、异常值 | 直方图 bins 会影响形状;箱线图异常点不等于错误数据。 |
| 长尾/极度不均匀变量 | log 坐标、CDF/CCDF | plt.xscale(“log”), CDF/CCDF 手写 | 尾部比例、是否少数样本占大头 | log 要处理 0/负数;CCDF 是 P(X>x)。 |
| 判断是否近似正态 | 偏度/峰度、直方图、QQ 图、SW/AD | x.skew(), x.kurt(), qqplot(), shapiro(), anderson() | p<α 拒绝正态;QQ 点接近线说明接近理论分布 | p 大不是证明正态;图示法较主观。 |
| 一组连续样本 vs 固定值 | 单样本 t 检验 | stats.ttest_1samp() | p<α 表示均值与固定值有显著差异 | H0 是均值等于固定值;注意单/双侧。 |
| 同一对象前后/两方法配对比较 | 配对样本 t 检验 | stats.ttest_rel() | p<α 表示配对差异显著 | 样本必须一一对应且长度相等。 |
| 两组独立连续样本比较 | 独立样本 t 检验 | stats.ttest_ind() | p<α 表示两组均值显著不同 | 方差不齐时考虑 equal_var=False。 |
| 三组及以上均值比较 | 单因素 ANOVA + Tukey | stats.f_oneway(), MultiComparison().tukeyhsd() | ANOVA 显著说明至少两组不同,Tukey 看哪两组不同 | ANOVA 不能直接告诉哪组与哪组不同。 |
| 分类变量比例或两个分类变量关系 | 卡方检验 | stats.chisquare(), stats.chi2_contingency() | p<α 表示实际比例与期望比例不同,或两个分类变量有关 | 要求频数表;不是连续均值检验。 |
| 样本分布 vs 理论分布/两样本分布 | K-S 检验 | stats.kstest(), stats.ks_2samp() | p<α 表示分布差异显著 | 需区分一组对理论分布和两组样本比较。 |
| 两个连续变量关系 | 散点图 + Pearson/Spearman | sns.scatterplot(), pearsonr(), spearmanr() | 方向、强度、线性/单调关系 | 必须先看散点图;相关不等于因果。 |
| 多个数值变量两两关系 | 相关矩阵、热力图、散点图矩阵 | df.corr(), sns.heatmap(), sns.pairplot() | 哪些变量同向/反向/冗余 | 变量太多时图拥挤;颜色图例要看清。 |
| 三个变量关系 | 气泡图/颜色映射散点图 | sns.scatterplot(size=, hue=) | 第三变量如何随 x、y 变化 | 点大小映射应有图例;遮挡可调 alpha。 |
| 多个观测变量背后潜在结构 | 因子分析 | factor_analyzer | KMO/Bartlett、因子个数、loading、因子命名 | 不适合的数据不要强行做;命名要基于高载荷变量。 |
| 降维并构造综合指标 | PCA | sklearn.decomposition.PCA | 解释率、累计解释率、主成分 loading | 单位不同先标准化;主成分不一定有自然含义。 |
6. 公式与指标总结#
| 公式/指标 | 表达式 | 符号含义 | 适用条件 | 计算步骤/直观解释 | 考试易错点 |
|---|---|---|---|---|---|
| 均值 | μ = (1/n)Σxᵢ | xᵢ:第 i 个样本;n:样本数 | 数值变量中心位置 | 所有值求和除以个数 | 受极端值影响。 |
| 中位数 | 排序后位于中间的值 | 奇数取中间,偶数取中间两个均值 | 偏态或有极端值时更稳健 | 排序后取位置 | 不要对未排序数据直接取“中间行”。 |
| 方差/标准差 | Var = Σ(xᵢ-μ)²/n;Std = sqrt(Var) | 衡量离散程度 | 连续数值变量 | 先求均值,再求平方偏差均值 | 样本方差常用 n-1;np.var 默认 n。 |
| 极差 | Range = max(x)-min(x) | 最大值、最小值 | 粗略衡量离散 | 最大减最小 | 极易受异常值影响。 |
| 变异系数 | CV = Std / Mean | Std:标准差;Mean:均值 | 比较不同量纲/均值规模的相对波动 | 标准差除以均值 | 均值接近 0 时不稳定。 |
| z 分数 | zᵢ=(xᵢ-μ)/σ | μ:均值;σ:标准差 | 标准化、异常值识别 | 每个样本分别计算 | 一列数据对应一列 z 分数。 |
| IQR | IQR=Q3-Q1 | Q1/Q3:25%/75% 分位数 | 箱线图和异常值判定 | 求四分位差 | 上下须通常在 1.5IQR 范围内。 |
| 箱线图异常阈值 | 下界=Q1-1.5IQR;上界=Q3+1.5IQR | IQR:四分位距 | 异常值初筛 | 超出边界的点标为异常点 | 异常点不一定是错误数据。 |
| 基尼系数 | G = A/(A+B);补充:也可由 Lorenz 曲线面积计算 | A:绝对平等线与 Lorenz 曲线间面积;A+B:45°线下三角形面积 | 衡量不均衡/集中度 | 排序→累计比例→画 Lorenz 曲线→求面积比 | 必须按值从小到大排序;阈值解释要看领域。 |
| CDF | F(x)=P(X≤x) | X:随机变量;x:阈值 | 累积比例、分布比较 | 排序后累计样本比例 | CDF 上升快处样本集中。 |
| CCDF | 1-F(x)=P(X>x) | F(x):CDF | 长尾/尾部概率 | 1 减 CDF | 读作“超过 x 的比例”。 |
| 偏度 | Skewness ≈ E[(X-μ)³]/σ³ | 三阶标准化矩 | 判断不对称性 | 正值通常右偏,负值通常左偏 | 看尾巴方向;课程经验阈值 |偏度|≤3。 |
| 峰度 | Kurtosis ≈ E[(X-μ)⁴]/σ⁴ | 四阶标准化矩 | 判断尖峭/尾部厚度 | 越大通常越尖/尾越厚 | 不同软件对峰度定义不同;课程经验阈值 |峰度|≤10。 |
| Pearson r | r = Σ[(xᵢ-x̄)(yᵢ-ȳ)] / sqrt(Σ(xᵢ-x̄)²Σ(yᵢ-ȳ)²) | x,y:两个连续变量 | 线性相关 | 标准化协方差 | 适用条件:连续、近似正态、线性。 |
| t 检验思想 | t = 均值差 / 标准误 | 标准误反映抽样波动 | 比较均值差异 | 计算 t 值并得到 p 值 | 关注均值;配对/独立要分清。 |
| ANOVA F | F = 组间变异 / 组内变异 | 组间变异:因素造成;组内变异:随机误差 | 三组及以上均值比较 | 若 F 大且 p 小,拒绝均值相等 | 显著后只说明至少两组不同。 |
| PCA 主成分 | Pⱼ=aⱼ1X1+aⱼ2X2+…+aⱼmXm | a:特征向量/权重 | 线性降维 | 求协方差或相关矩阵特征值/特征向量 | 变量单位不同或方差差异大时先标准化。 |
| PCA 解释率 | 解释率ⱼ=λⱼ/Σλ | λⱼ:第 j 个特征值 | 选择主成分数量 | 计算每个主成分解释方差比例与累计比例 | 累计解释率过低则代表性不足。 |
| 因子 loading | loading 表示因子对变量的解释/关联强度 | 经验阈值常取 |loading|>0.3 | 因子解释与命名 | 看每个因子在哪些变量上 loading 高 | 因子命名不能脱离变量含义。 |
7. 课堂重点与考试提示#
7.1 必背概念#
- EDA = 定量方法 + 可视化工具,目标是理解特征、识别结构、抽取重要变量、发现异常、辅助参数设定。
- EDA 与 CDA 区别:EDA 无预设假设、生成假设、主要用图形方法;CDA 以假设开始、检验零假设、主要用统计模型。
- 描述性统计三类关注:中心位置、发散程度、偏差程度。
- 分布图选择:类别变量用表格/柱状图;连续变量用直方图/KDE;长尾变量考虑 log 坐标、CDF/CCDF。
- 正态性检验三类方法:数值法、图示法、统计检验法。
- 参数检验与非参数检验:近似正态连续数据可用参数检验;非正态/分类/分布未知常用非参数检验。
- Pearson 三条件:连续数据、近似正态、线性关系。
- 因子分析三步:适用性检验 → 提取因子并看解释率 → 看 loading 并命名。
7.2 必会代码#
- pandas:
read_csv、head、describe、value_counts、groupby、pivot_table、reindex(fill_value=0)。 - numpy:
mean、median、var、std、ptp、z 分数。 - matplotlib/seaborn:柱状图、直方图、箱线图、小提琴图、散点图、热力图、pairplot、保存图片。
- scipy:
shapiro、anderson、ttest_1samp、ttest_rel、ttest_ind、f_oneway、chisquare、chi2_contingency、kstest。 - statsmodels:
qqplot、MultiComparison(...).tukeyhsd()。 - sklearn/factor_analyzer:PCA、KMO、Bartlett、因子载荷。
7.3 必会分析思路#
| 题目类型 | 答题步骤 |
|---|---|
| 单变量分析题 | 1. 说明变量类型;2. 给出中心/离散/异常指标;3. 画合适分布图;4. 判断偏态/长尾/异常;5. 如需统计检验,先考虑正态性。 |
| 两变量关系题 | 1. 先画散点图;2. 判断形态是否线性;3. 根据条件选 Pearson 或 Spearman;4. 报告相关方向、强度和 p 值;5. 明确相关不等于因果。 |
| 多组均值比较题 | 1. 判断组数和配对关系;2. 一组 vs 常数用单样本 t;两组配对用配对 t;两组独立用独立 t;三组以上用 ANOVA;3. 解释 statistic 与 p 值;4. ANOVA 后必要时做 Tukey。 |
| 分类变量关系题 | 1. 构造频数表/交叉表;2. 选择卡方检验;3. 报告 χ²、p、自由度;4. 结合比例表解释关系方向。 |
| 因子分析题 | 1. KMO/Bartlett 判断适用性;2. 特征值/碎石图/解释率决定因子个数;3. 根据 loading 高的变量给因子命名;4. 说明降维的信息损失和解释率。 |
| 可视化开放题 | 1. 提出明确研究问题;2. 数据清洗和变量构造;3. 选择图表和统计指标;4. 解释图表发现;5. 指出局限性和下一步。 |
7.4 高频易错点#
- 只算相关系数不画散点图:老师明确强调这是错误做法。
- Pearson 滥用:非连续、非正态、非线性数据不应机械使用 Pearson。
- 配对 t 与独立 t 混淆:配对必须一一对应且样本数相等。
- ANOVA 解释过度:p 小只说明至少两组不同,具体哪两组需 Tukey 等事后检验。
- 长尾分布图不可读:需要考虑对数坐标、CDF/CCDF 或合理分组。
- 时间序列缺失年份未补齐:折线图会出现空洞或误导趋势,应
reindex补 0。 - 多折线重合被覆盖:两列数据可能完全相同,后画线覆盖前画线,必须检查数据。
- 相关矩阵变量方向不一致:若某指标方向与其他指标相反,建模前可能要反向处理。
- 图表美化忽视可读性:横轴标签重叠、颜色不一致、图例缺失、网格线过多/过少都会影响表达。
7.5 可能出题方式#
- 给一段代码,问输出的统计量或 p 值如何解释。
- 给变量类型和研究问题,问应选什么图或什么检验方法。
- 给 QQ 图/直方图/相关矩阵,要求判断分布或变量关系。
- 给 loading 表,要求确定因子个数并命名因子。
- 给长尾数据分布,要求改进可视化方案。
- 开放式 EDA:要求提出问题、做图、给统计量并解释。
8. 期末复习版精简笔记#
- EDA:无预设假设,用定量方法和可视化工具理解数据、发现结构、识别变量和异常,为后续 CDA/建模做准备。CDA:有假设,检验 H0。
- 单变量三步:描述性统计(中心/离散/偏离)→ 分布图(类别柱状图、连续直方图/KDE、长尾 CDF/CCDF/log)→ 正态性/差异检验。
- 描述性统计:中心=均值/中位数/众数;离散=极差/方差/标准差/CV;偏离=z 分数。z=(x-mean)/std,每个样本一个 z。
- 偏态:右偏=右尾长,众数<中位数<均值;左偏=左尾长,均值<中位数<众数。不要看峰的位置判断偏态。
- 正态检验:数值法看偏度/峰度;图示法看直方图、QQ 图;统计检验用 SW/AD。SW 的 H0 是正态,p<α 拒绝正态。
- 非正态处理:可尝试 log、sqrt;log-normal 是取对数后近似正态。含 0 用 log1p。
- 检验选择:一组 vs 常数
ttest_1samp;两组配对ttest_rel;两组独立ttest_ind;三组以上f_oneway;分类频数chi2;分布比较K-S。 - 双变量:先画散点图,再算相关系数。Pearson 只适合连续、近似正态、线性;Spearman 用于秩/单调关系。相关≠因果。
- 多变量:三变量可气泡图;多变量看热力图/相关矩阵/pairplot;高度相关变量建模可择代表;方向相反变量需反向处理。
- 因子分析三步:KMO/Bartlett 看是否适合;特征值>1/碎石图/解释率选因子数;看 loading 给因子命名。
- PCA:线性组合提主成分;单位不同先标准化;看特征值、碎石图、累计解释率;PCA 找最大方差方向,FA 找潜在共同因子。
- 作图常见坑:标签重叠要旋转/tight_layout;分组柱要 width 偏移;多折线重合要查数据;时间序列缺年份要补 0;颜色映射前后一致。
9. 自测题与参考答案
以下题目贴近 PPT 与课堂讲法,答案写在每题后。
1. 选择题#
EDA 与 CDA 的主要区别是( )。A. EDA 只能用于小样本,CDA 只能用于大样本;B. EDA 通常不以预设假设开始,CDA 通常从假设开始;C. EDA 不能画图;D. CDA 不使用统计模型。
标准答案与解析:答案:B。解析:PPT 和课堂都强调 EDA 先探索并生成假设,CDA 先有假设并检验零假设。
2. 选择题#
若一个变量是连续变量且想看其分布区间,应优先使用( )。A. 柱状图;B. 直方图;C. 饼图;D. 雷达图。
标准答案与解析:答案:B。解析:连续变量按区间分箱展示频数/密度,用直方图;柱状图更适合类别变量。
3. 选择题#
Pearson 相关系数适用条件不包括( )。A. 两变量连续;B. 两变量近似正态;C. 关系大致线性;D. 两变量必须是分类变量。
标准答案与解析:答案:D。解析:Pearson 用于连续变量的线性相关。
4. 选择题#
三组射击成绩均值是否存在差异,优先使用( )。A. 单样本 t 检验;B. 配对 t 检验;C. 单因素 ANOVA;D. 饼图。
标准答案与解析:答案:C。解析:三组及以上均值比较用 ANOVA;若显著再做 Tukey 判断哪两组不同。
5. 选择题#
SW 检验中 p<0.05 通常表示( )。A. 无法拒绝正态性;B. 拒绝正态性假设;C. 样本均值为 0;D. 两变量相关。
标准答案与解析:答案:B。解析:SW 的 H0 是样本来自正态分布,p 小拒绝 H0。
6. 判断题#
EDA 的主要目标之一是生成假设,而 CDA 的主要目标之一是检验假设。
标准答案与解析:答案:正确。解析:这是 PPT p.4 和课堂讲解的核心区别。
7. 判断题#
z 分数是一列数据计算出一个总数。
标准答案与解析:答案:错误。解析:老师强调一列样本会得到一列 z 分数,每个样本都有自己的 z 分数。
8. 判断题#
相关系数相同的两组变量关系形态一定相同。
标准答案与解析:答案:错误。解析:课堂强调相关系数不是万能的,同一相关系数可能对应完全不同散点结构。
9. 判断题#
ANOVA 显著后,可以直接知道具体哪两组有差异。
标准答案与解析:答案:错误。解析:ANOVA 显著只说明至少两组不同,需要 Tukey 等事后检验。
10. 判断题#
因子分析中,KMO 很低时仍然应该继续提取因子。
标准答案与解析:答案:错误。解析:KMO <0.6(或更严格 <0.5)说明不适合做因子分析。
11. 简答题#
请用标准表述说明“探索式数据分析”的含义。
标准答案与解析:答案:探索式数据分析是指使用定量方法和可视化工具,对数据集中变量的规律、趋势、隐含结构、离散情况、异常情况等进行分析,目标是理解数据特征、识别潜在结构、抽取重要变量、发现异常值并辅助后续建模或参数设定。
12. 简答题#
柱状图和直方图有什么区别?
标准答案与解析:答案:柱状图通常用于类别变量或离散取值,各柱之间可以有间隔;直方图用于连续变量,横轴是连续数值区间,柱子通常相邻,用于展示变量在各区间的频数或密度。
13. 简答题#
为什么老师强调“相关系数不是万能的”?
标准答案与解析:答案:因为相关系数只用一个数概括关系,尤其 Pearson 只捕捉线性关系;相同相关系数可能对应不同散点结构,也可能被异常值影响。正确做法是先画散点图,再结合相关系数解释。
14. 简答题#
因子分析的三步是什么?
标准答案与解析:答案:第一,做 KMO 和 Bartlett 球形检验,判断数据是否适合因子分析;第二,依据特征值、碎石图和方差解释率决定提取几个因子;第三,分析因子载荷 loading,结合高载荷变量含义对因子命名。
15. 代码阅读题#
代码:stat, p = stats.shapiro(x); print(p)。若输出 p=0.003,在 α=0.05 下如何解释?
标准答案与解析:答案:拒绝“x 来自正态分布”的原假设,认为 x 不符合或不近似符合正态分布。解析:SW 检验 H0 为正态,p<α 拒绝 H0。
16. 代码阅读题#
代码:stats.ttest_rel(a, b),但 a 有 10 个值,b 有 12 个值。问题在哪里?
标准答案与解析:答案:配对样本 t 检验要求两个样本一一对应且长度相等。若两组独立且长度不同,应考虑 stats.ttest_ind(a, b),前提是研究问题确实是独立样本均值比较。
17. 代码阅读题#
代码:df.groupby("year")["paper_id"].count().plot() 用于画年度发文量。若某些年份没有记录,图上可能出现什么问题?如何处理?
标准答案与解析:答案:缺失年份不会显示,折线可能误导趋势或结构不好看。可构造完整年份序列并 reindex(full_years, fill_value=0) 补齐。
18. 代码补全题#
补全代码计算分类变量 doc_type 的频数并画柱状图:counts = df["doc_type"].____(); counts.plot(kind="____")
标准答案与解析:答案:value_counts;bar。解析:类别频数用 value_counts,柱状图适合类别分布。
19. 代码补全题#
补全 Pearson 与 Spearman 相关系数:from scipy.stats import ____, ____; pearsonr(x,y); spearmanr(x,y)
标准答案与解析:答案:pearsonr, spearmanr。解析:scipy.stats 提供两种相关系数函数。
20. 代码补全题#
补全 CDF 计算:x_sorted=np.sort(x); cdf=np.arange(1, len(x_sorted)+1) / ____
标准答案与解析:答案:len(x_sorted)。解析:CDF 是排序后第 i 个样本对应的累计比例 i/n。
21. 数据分析应用题#
某数据集包含论文引用次数,大多数论文引用次数很低,少数论文引用次数极高。请说明如何做 EDA。
标准答案与解析:答案:先用 describe 查看最值、分位数和离散程度;画直方图初看分布;由于长尾明显,进一步使用 log 坐标、CDF 或 CCDF 查看尾部;可报告中位数、上四分位数、极端高引用论文比例;解释少数高引用论文对均值的影响,必要时用 log1p 变换。
22. 数据分析应用题#
要研究性别与是否观看直播是否有关,应该如何分析?
标准答案与解析:答案:两个变量都是分类变量,应先构造交叉表 pd.crosstab(gender, watch_live),查看各格频数和比例;再用 stats.chi2_contingency 做交叉表卡方检验;若 p<α,认为性别与是否观看直播存在统计关联;最后结合比例解释关系方向。
23. 数据分析应用题#
给你 25 个问卷题项,老师说背后可能对应“大五人格”。请给出因子分析步骤。
标准答案与解析:答案:清洗问卷题项并处理反向题;用 KMO 和 Bartlett 判断是否适合因子分析;用特征值>1、碎石图和累计解释率确定因子数;设定因子数并旋转得到 loading;根据高载荷题项给因子命名,如认同性、责任感、外向性、神经质、开放性;报告解释率和局限。
24. 数据分析应用题#
某热力图显示 4 个变量高度正相关。后续机器学习建模应如何处理?
标准答案与解析:答案:这些变量信息冗余,可以结合业务含义选择一个或少数代表变量,或用 PCA/因子分析降维,避免把高度重复信息全部放入模型。若某变量方向与其他指标相反,应考虑反向处理。
10. 一页纸考前速览#
| 模块 | 10 分钟速记 |
|---|---|
| EDA/CDA | EDA:无预设假设、生成假设、图形方法为主;CDA:从假设开始、检验 H0、统计模型为主。 |
| 单变量指标 | 中心:均值/中位数/众数;离散:极差/方差/标准差/CV;偏离:z=(x-mean)/std;异常:箱线图 1.5IQR。 |
| 分布图 | 类别:value_counts + bar;连续:hist/KDE/box/violin;长尾:log、CDF、CCDF;右偏=右尾长,均值>中位数>众数。 |
| 正态检验 | 数值法:偏度/峰度;图示法:直方图、QQ;统计法:SW、AD。SW H0=正态,p<α 拒绝。非正态可 log/sqrt。 |
| 检验选择 | 一组 vs 常数:ttest_1samp;配对两组:ttest_rel;独立两组:ttest_ind;三组以上:f_oneway + Tukey;分类频数:χ²;分布比较:K-S。 |
| 双变量 | 先画散点图,再算相关系数。Pearson:连续+正态+线性;Spearman:秩/单调。相关≠因果;相关系数不是万能的。 |
| 多变量 | 三变量:气泡图;多变量:heatmap/pairplot;高相关变量可择代表;方向相反变量可反向处理。 |
| 因子分析 | 三步:KMO/Bartlett → 特征值/碎石图/解释率选因子 → loading 命名。KMO>0.8 很适合,<0.6/0.5 不适合。 |
| PCA | 线性组合得主成分;单位不同先标准化;选特征值大、累计解释率高的主成分;PCA 找方差方向,FA 找潜在共同因子。 |
| 作图易错 | 标签重叠:rotation/tight_layout;分组柱:width 偏移;时间缺年份:reindex 补 0;多折线重合:查数据;颜色映射保持一致。 |
考前最后一句:遇到 EDA 题,不要只写代码或只画图;标准答题应包含“研究问题 → 数据处理 → 指标/图表 → 结果解释 → 局限或下一步”。
第 6 章 机器学习基础#
内容来源:原文件内容。 课程 PPT《6-机器学习基础-20260511.pdf》、2026-05-11 课堂转录与同日上机补充转录。
1. 本讲/本章知识框架#
1.1 总体结构#
机器学习的概念:理解为主
机器学习的定义:通过经验/数据改进算法的性能。
三个关键词:算法、经验、性能。
AI、ML、DL 的关系:人工智能是大范畴,机器学习是实现人工智能的重要方法,深度学习是机器学习中的一类方法。
机器学习一般流程:数据集 → 数据清洗 → 特征工程 → 训练数据/新数据 → 学习算法 → 训练模型 → 评分/评估 → 应用。
机器学习局限:模型能给预测,但未必能给出充分可解释的理由。
机器学习经典问题:理解任务边界
分类 Classification:预测离散类别,如垃圾邮件检测、图像识别。
回归 Regression:预测连续数值,如股价预测、房屋定价。
聚类 Clustering:无标签条件下把相似样本自动分组,如客户细分、异常检测、图像分割。
利用 scikit-learn 进行机器学习:会用为主
预处理:标准化、归一化、标称特征编码、离散化、二值化、多项式特征、定制转换器。
分类:LogisticRegression、DecisionTreeClassifier、GaussianNB、SVC 等。
回归:LinearRegression、DecisionTreeRegressor 等。
聚类:KMeans、AgglomerativeClustering、DBSCAN。
评价:分类指标、回归指标、聚类指标。
1.2 知识点之间的关系#
| 层级 | 核心问题 | 相关内容 | 考试/作业关注 |
|---|---|---|---|
| 概念层 | 机器学习是什么 | 算法、经验、性能;AI/ML/DL;X、y、f | 能写出标准定义,能解释 X、y、f |
| 流程层 | 一个机器学习任务怎么做 | 数据清洗、特征工程、训练/测试、模型训练、评估 | 能按步骤说明建模流程 |
| 任务层 | 该用分类、回归还是聚类 | 离散标签、连续数值、无标签分组 | 能根据题意选方法 |
| 工具层 | 如何用 sklearn 实现 | fit、transform、predict、fit_predict、score | 能补全/阅读代码 |
| 评价层 | 模型好不好 | accuracy、precision、recall、F1、AUC、MSE、R²、silhouette | 能解释指标含义和适用场景 |
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| 机器学习 | Machine Learning | 通过数据或经验自动改进算法,使程序在某性能标准上表现更好。 | 分类、回归、聚类、预测、识别。 | 不等于所有人工智能;也不等于深度学习。 | “请解释机器学习的三个关键词。” |
| 人工智能 | Artificial Intelligence | 让机器完成类似人类智能行为的总称。 | 搜索、规则系统、机器学习、深度学习等。 | 机器学习只是 AI 的一种实现路径。 | “AI、ML、DL 的关系是什么?” |
| 深度学习 | Deep Learning | 以深层神经网络为核心的机器学习方法。 | 图像、语音、文本、大模型等复杂数据。 | 深度学习不是唯一选择;结构化小数据可用传统机器学习。 | “为什么还要学习传统机器学习?” |
| 算法 | Algorithm | 实现学习任务的计算过程或模型训练方法。 | 逻辑回归、决策树、KMeans 等。 | 未训练前只是算法/模型类;训练后才得到具体模型。 | “为什么算法是机器学习关键词之一?” |
| 经验/数据 | Experience/Data | 模型用于学习的样本、历史记录、观测数据。 | 训练模型、估计参数。 | 数据质量影响学习结果;不是所有数据都可直接喂给模型。 | “机器学习中的经验通常指什么?” |
| 性能 | Performance | 衡量模型表现的指标,如准确率、MSE、R²、AUC。 | 模型评价、模型选择。 | 不同任务指标不同;训练集表现好不代表泛化好。 | “分类与回归评价指标有何区别?” |
| 样本 | Sample/Instance | 数据表中的一行,代表一个对象或观测。 | 学生、邮件、房屋、交易等。 | 样本数是行数,不是特征数。 | “一行数据通常表示什么?” |
| 特征 | Feature | 描述样本的输入变量,通常对应数据表的一列。 | 颜色、大小、成绩、面积等。 | 特征不等于标签;特征工程在列上构造新信息。 | “什么是 feature?” |
| 标签/目标 | Label/Target | 需要预测的输出变量 y。 | 分类标签、连续数值、甜度等。 | 聚类通常没有 y;分类 y 为离散,回归 y 为连续。 | “分类、回归、聚类中的 y 有何不同?” |
| 映射函数 | Mapping Function | 学习从 X 到 y 的函数 f,使新样本 X_new 可预测 y_pred。 | 监督学习。 | f 不是手写规则,而是由算法从数据中学得。 | “芒果例子中的 X、y、f 分别是什么?” |
| 数据清洗 | Data Cleaning | 删除错误数据、处理缺失值、修正异常格式等。 | 原始数据进入模型前。 | 清洗偏向通用处理,特征工程更依赖场景知识。 | “数据清洗为什么必要?” |
| 特征工程 | Feature Engineering | 根据场景、数据和模型特性构造或变换特征。 | 提升模型可用性与表现。 | 不是简单清洗;可解释特征与不可解释变换都可能属于特征工程。 | “举例说明特征工程。” |
| 训练集 | Training Set | 用于拟合模型参数的数据。 | model.fit(X_train, y_train)。 | 不能用测试集 fit 预处理器。 | “fit 应该在什么数据上做?” |
| 测试集 | Test Set | 用于评价模型对新样本预测能力的数据。 | 评估泛化能力。 | 测试集表现比训练集更重要。 | “为什么要划分训练集和测试集?” |
| 分类 | Classification | 识别对象所属的离散类别。 | 垃圾邮件、图像类别、是否高收入。 | 分类标签是已有类别,不是自动发现新组。 | “判断一个任务是不是分类。” |
| 回归 | Regression | 预测连续值属性。 | 房价、温度、股价、糖尿病指标。 | LogisticRegression 名字有 regression,但用于分类。 | “逻辑回归是分类还是回归?” |
| 聚类 | Clustering | 在无标签条件下将相似样本分到同一组。 | 客户细分、异常检测、图像分割。 | 聚类结果的标签编号没有天然语义,需业务解释。 | “聚类和分类的区别是什么?” |
| 标准化 | Standardization | 对每个特征变换为均值 0、方差 1。 | 量纲不同、距离/梯度敏感模型。 | StandardScaler 按特征列处理。 | “StandardScaler 做了什么?” |
| 归一化 | Normalization | 将每个样本向量缩放到相同模长。 | 文本向量空间模型、相似度计算。 | 归一化按样本行处理,不同于标准化按列。 | “标准化和归一化区别?” |
| 标称特征编码 | Categorical Encoding | 将类别变量转为模型可处理的数值。 | 性别、地区、品牌等。 | OrdinalEncoder 可能引入虚假顺序;OneHot 会增维。 | “何时用 OneHotEncoder?” |
| 离散化/分箱 | Discretization/Binning | 将连续变量分为若干箱。 | 分段分析、规则化、预处理。 | 分箱会损失连续信息。 | “KBinsDiscretizer 的作用?” |
| 逻辑回归 | Logistic Regression | 用线性函数与逻辑函数建模类别概率的分类模型。 | 二分类、多分类基础任务。 | 名字叫回归,但课程强调它是分类模型。 | “LogisticRegression 为什么是分类?” |
| 决策树 | Decision Tree | 通过一系列特征划分进行分类或回归。 | 可解释建模、规则提取。 | 树太深易过拟合;可视化不要展示过大树。 | “max_depth 对模型有什么影响?” |
| KMeans | K-Means | 通过最小化样本到簇中心距离进行划分聚类。 | 球形、相对均衡、簇数已知的数据。 | K 要预先指定;不适合明显非球形或严重重叠数据。 | “KMeans 适用条件是什么?” |
| 层次聚类 | Hierarchical Clustering | 按层次逐步合并或划分样本,形成树状结构。 | 探索样本间层次关系。 | 凝聚 AGNES 与划分 DIANA 方向相反。 | “如何理解 dendrogram?” |
| DBSCAN | Density-Based Spatial Clustering | 基于密度可达关系聚类,可识别噪声点。 | 非球形簇、异常点检测。 | eps、min_samples 对结果影响大。 | “DBSCAN 与 KMeans 的区别?” |
| eps / Epsilon | Epsilon Neighborhood Radius | DBSCAN 中定义邻域大小的半径阈值。 | 计算点的邻居、判断密度、连接簇。 | 受特征尺度和距离度量影响,做 DBSCAN 前通常要标准化。 | “为什么 DBSCAN 前常做 StandardScaler?” |
| MinPts/min_samples | Minimum Points | DBSCAN 中判断核心点所需的最少邻域样本数。 | 控制哪些点可作为簇扩展的核心。 | 值过大可能把很多点判为噪声,值过小可能产生碎簇。 | “min_samples 如何影响聚类结果?” |
| 核心点 | Core Point | eps 邻域内样本数不少于 min_samples 的点。 | DBSCAN 中从高密度点向外扩展簇。 | 核心点不等于簇中心;DBSCAN 不是用一个中心代表簇。 | “核心点和 KMeans 簇中心有何不同?” |
| 噪声点/离群点 | Noise/Outlier | 不能由核心点密度连接到任何簇的点。 | 异常检测、清洗异常样本。 | sklearn 中标签为 -1,不是普通簇编号。 | “DBSCAN 输出 -1 表示什么?” |
| 混淆矩阵 | Confusion Matrix | 统计真实类别与预测类别组合的计数矩阵。 | 分类错误结构分析。 | confusion_matrix(y_true, y_pred) 中真实标签在前、预测标签在后。 | “混淆矩阵如何看分类错误?” |
| ROC/AUC | Receiver Operating Characteristic / Area Under Curve | ROC 描述不同阈值下 TPR 与 FPR 的变化;AUC 是曲线下面积。 | 二分类模型概率排序能力比较。 | 通常需要正类概率或 decision score,而不是硬分类标签。 | “画 ROC 曲线需要什么输入?” |
3. 重点知识详解#
3.1 机器学习定义与三个关键词#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 机器学习是用数据或以往经验来优化计算机程序性能标准的方法。标准答题可写为:机器学习通过算法从经验数据中学习规律,并在指定性能指标上改进模型表现。 |
| 直观理解 | 人学习要看教材、例子和经验;机器学习也要看数据。模型不是凭空给出预测,而是利用历史样本形成从 X 到 y 的映射。 |
| PPT 中对应内容 | PPT 第 3 页给出定义,并明确三个关键词:算法、经验、性能。 |
| 老师课堂强调 | 老师多次解释“经验更直观地说就是数据”,“算法通过数据学习,目标是提高性能”。 |
| 典型例子 | 用历史天气数据预测晚上是否下雨;用历史股价数据预测未来价格;用芒果颜色、大小、产地预测甜度。 |
| 可能考点 | 解释三关键词;说明机器学习与普通手写规则的区别;说明什么是 X、y、f。 |
| 常见错误 | 把机器学习理解为“只要有程序自动运行”;忽视性能指标;把训练集准确率当作最终能力。 |
3.2 AI、机器学习与深度学习的关系#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | AI 是最大范畴;ML 是实现 AI 的重要方法;DL 是 ML 中以深层神经网络为代表的一类方法。 |
| 直观理解 | 三者关系可理解为同心或嵌套:AI ⊃ ML ⊃ DL。 |
| PPT 中对应内容 | PPT 第 4 页图示了 AI、Machine Learning、Deep Learning 的历史关系。 |
| 老师课堂强调 | 深度学习解决复杂数据效果强,但传统机器学习在结构化、小规模、需要解释性或轻量部署时仍然有价值。 |
| 典型例子 | 图像识别、大模型多基于深度学习;银行可解释识别场景常用逻辑回归;互联网预测任务可能使用梯度提升类模型(课堂转录中“charging boss”疑为转录误差,可能指 boosting/GBDT 类方法)。 |
| 可能考点 | “为什么现在有深度学习还要学传统机器学习?” |
| 常见错误 | 认为机器学习等于深度学习;认为复杂模型一定优于简单模型。 |
3.3 机器学习一般流程#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 从原始数据出发,经数据清洗、特征工程、训练/测试划分、算法训练、模型评分与评估,最后用于新数据预测。 |
| 直观理解 | 建模不是“直接调用 fit”这么简单。原始数据通常脏、乱、缺失或量纲不同,需要整理成模型可学习的形式。 |
| PPT 中对应内容 | PPT 第 5 页流程图:Dataset → Data cleaning → Feature Engineering → Training Data/New Data → Learning Algorithm → Train Model → Score Model → Evaluate Model。 |
| 老师课堂强调 | 建模后不能直接用,必须评价;更关注模型对未知样本的预测能力,而不是只看历史训练数据表现。 |
| 典型例子 | 用历史股价训练模型,但最终关心的是明天股价预测是否可靠。 |
| 可能考点 | 写出机器学习流程;解释为什么需要测试集;解释数据清洗与特征工程区别。 |
| 常见错误 | 在全量数据上 fit 预处理器再划分;不做评估直接下结论;只报告训练集准确率。 |
3.4 机器学习局限:解释性问题#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 很多模型能够给出预测,但不一定能给出人类可理解的理由。 |
| 直观理解 | 模型可以预测“42 度”,但追问“为什么是 42”时,可能只给出参数和计算过程,不像规则系统那样易解释。 |
| PPT 中对应内容 | PPT 第 6 页漫画对比了没有机器学习时的具体指令与有机器学习时的数据驱动预测,并提出解释困难。 |
| 老师课堂强调 | 如果只要高性能预测,机器学习很合适;如果强依赖解释性,不一定总是最合适。 |
| 典型例子 | 银行、风控、医学等场景往往既看预测效果,也看解释性。 |
| 可能考点 | 说明机器学习的局限;比较规则系统与机器学习。 |
| 常见错误 | 认为模型分数高就一定可以直接决策;忽略可解释性、合规性、业务意义。 |
3.5 分类 Classification#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 分类是有监督学习任务,目标是学习从特征 X 到离散类别 y 的映射,并把新样本分到已有类别。 |
| 直观理解 | 已经知道训练样本属于“垃圾邮件/非垃圾邮件”“猫/狗/其他”等类别,模型学习后对新对象判定类别。 |
| PPT 中对应内容 | PPT 第 8 页:任务是识别对象所属类别;场景有垃圾邮件检测、图像识别;算法包括决策树、朴素贝叶斯、判别分析、神经网络、随机森林、贝叶斯网络、AdaBoost、深度学习等。 |
| 老师课堂强调 | 分类的 y 是离散标签;是“划分到已有类别”,不是自动发现类别。 |
| 典型例子 | 邮件服务器判断是否垃圾邮件;手机拍照识别美食、天空等场景并调整滤镜。 |
| 可能考点 | 给定任务判断是否分类;列举分类算法;解释分类与聚类区别。 |
| 常见错误 | 将连续数值预测误判为分类;把无标签分组误判为分类。 |
3.6 回归 Regression#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 回归是预测与对象相关的连续值属性。 |
| 直观理解 | 不是回答“属于哪类”,而是回答“数值是多少”。 |
| PPT 中对应内容 | PPT 第 12 页:任务是预测连续值属性;场景为股价预测、房屋定价;算法包括线性回归、SVR、K 近邻、决策树、随机森林等。 |
| 老师课堂强调 | 回归和分类都可以看作学习 X 到 y 的映射,关键区别在 y 的类型:连续值 vs 离散类别。 |
| 典型例子 | 根据房屋面积、位置、楼层预测房价;根据历史数据预测糖尿病指标。 |
| 可能考点 | 判断任务是否回归;解释线性回归基本思想;说明回归评价指标。 |
| 常见错误 | 看到模型名有 regression 就一定认为是回归任务;例如 LogisticRegression 是分类模型。 |
3.7 聚类 Clustering#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 聚类是无监督学习任务,在没有标签 y 的情况下,根据相似性把样本自动分组。 |
| 直观理解 | “物以类聚”。不知道组名和组数的业务含义,只是根据特征相似度先分组,再解释。 |
| PPT 中对应内容 | PPT 第 13–14 页:聚类用于固有结构识别、异常检测、数据预处理;算法包括层次聚类、KMeans、K-medoids、DBSCAN、OPTICS、Mean Shift、谱聚类等。 |
| 老师课堂强调 | 聚类没有 y,fit 时通常只传 X;聚类结果编号本身没有业务语义,需要解释。 |
| 典型例子 | 根据客户消费行为做客户细分;根据用户位置信息做商业选址;识别异常交易。 |
| 可能考点 | 聚类与分类区别;KMeans 适用条件;如何解释聚类结果。 |
| 常见错误 | 把聚类标签 0/1/2 当作有大小关系;不做标准化直接聚类;不解释每类特征。 |
3.8 scikit-learn 基本使用思想#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | scikit-learn 是基于 Python 的机器学习工具包,建立在 NumPy、SciPy、matplotlib 上,提供预处理、分类、回归、聚类、模型选择与评价等功能。 |
| 直观理解 | 课程要求不是深入推导算法,而是会用统一接口完成基础分析。 |
| PPT 中对应内容 | PPT 第 16–17 页介绍 sklearn 的特点和任务模块。 |
| 老师课堂强调 | 本讲“会用”指简单会用:能按默认方式完成预处理、分类、回归、聚类,并能做基本评价。 |
| 典型例子 | model = LogisticRegression(); model.fit(X_train, y_train); pred = model.predict(X_test)。 |
| 可能考点 | 补全 fit/predict/transform;说明 train_test_split 的作用。 |
| 常见错误 | 忘记实例化括号;把 fit_transform 用在测试集;X 和 y 打乱不同步。 |
3.9 数据预处理#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 数据预处理把原始数据转换成模型可接受、表现更稳定的形式。 |
| 直观理解 | 不同模型对数据形式有要求;例如距离敏感模型受量纲影响,类别变量不能直接作为字符串输入多数模型。 |
| PPT 中对应内容 | PPT 第 18–29 页:标准化、归一化、标称特征编码、离散化、二值化、多项式特征、定制转换器等。 |
| 老师课堂强调 | 训练集和测试集必须使用同一个 scaler/encoder 的规则:训练集上 fit,测试集上只 transform。 |
| 典型例子 | StandardScaler().fit(X_train) 保存训练集均值和标准差,然后对 X_train 与 X_test 使用同一个 scaler 转换。 |
| 可能考点 | 标准化与归一化区别;OneHot 与 Ordinal 区别;为什么测试集不能重新 fit。 |
| 常见错误 | 数据泄漏;训练/测试转换规则不一致;对无序类别使用整数编码后误导模型。 |
3.10 普通最小二乘与线性回归#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 普通最小二乘通过最小化预测值与真实值的平方误差和来求系数 w。 |
| 直观理解 | 找一条线或一个超平面,使数据点到预测线的整体误差最小。 |
| PPT 中对应内容 | PPT 第 31–33 页给出目标函数、预测公式和 diabetes 数据集示例。 |
| 老师课堂强调 | 调用流程是加载数据、划分训练/测试、实例化 LinearRegression、fit、predict、计算 MSE/R²、可视化。 |
| 典型例子 | 用糖尿病数据集中一个特征预测目标值,并画散点与拟合直线。 |
| 可能考点 | 写出 OLS 优化目标;解释 MSE 和 R²;补全 fit/predict。 |
| 常见错误 | 只报告系数不评价误差;把测试集用于训练;忽略 X 需要二维数组。 |
3.11 逻辑回归 LogisticRegression#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 逻辑回归是分类模型,也称 logit regression、MaxEnt、log-linear classifier。它通过建模类别概率来完成分类。 |
| 直观理解 | 虽然名字含 regression,但预测的是类别或类别概率;它不是连续值回归模型。 |
| PPT 中对应内容 | PPT 第 34–37 页列出 LogisticRegression 与 L1/L2/Elastic-Net 正则化优化目标。 |
| 老师课堂强调 | 逻辑回归是分类模型,不要被名字误导。 参数 C 体现拟合准确与泛化能力的权衡;不同正则项和参数会得到不同模型。 |
| 典型例子 | 使用 digits 数据,标准化后训练不同正则化的 LogisticRegression,并比较系数与分类效果。 |
| 可能考点 | 判断 LogisticRegression 任务类型;解释 C 的大致作用;写分类训练模板。 |
| 常见错误 | 把 LogisticRegression 用来预测连续数值;忽略 max_iter;多分类时忘记 y 是类别标签。 |
3.12 决策树#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 决策树通过一系列基于特征值的划分完成分类或回归。分类叶节点给类别,回归叶节点给预测值。 |
| 直观理解 | 像一组 if-else 规则:按某特征是否小于阈值不断分裂,直到叶节点。 |
| PPT 中对应内容 | PPT 第 38–49 页回顾决策树,包含 DecisionTreeClassifier、predict_proba、可视化、export_graphviz、export_text、DecisionTreeRegressor。 |
| 老师课堂强调 | 决策树可视化适合展示规则,但报告中不要放过深、过宽的树;可限制 3–4 层。max_depth 影响复杂度,树越深不一定泛化越好。 |
| 典型例子 | 鸢尾花分类树;用 export_text 输出文本规则;用不同 max_depth 的树回归曲线比较欠拟合/过拟合。 |
| 可能考点 | 决策树如何分类/回归;predict 与 predict_proba 区别;max_depth 的影响。 |
| 常见错误 | 以为树越深越好;可视化树过大无法解释;不区分分类树和回归树。 |
3.13 朴素贝叶斯 GaussianNB#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | GaussianNB 是朴素贝叶斯分类器,假设特征条件似然服从高斯分布,并利用贝叶斯思想估计类别。 |
| 直观理解 | 根据各类别下特征出现/取值的概率,计算样本更可能属于哪一类。 |
| PPT 中对应内容 | PPT 第 50–51 页:sklearn.naive_bayes.GaussianNB(),高斯朴素贝叶斯用高斯函数估计特征似然值。 |
| 老师课堂强调 | 课程层面知道用途与调用即可,具体概率估计细节不展开。 |
| 典型例子 | model = GaussianNB(); model.fit(X_train, y_train); pred = model.predict(X_test)。 |
| 可能考点 | 朴素贝叶斯属于分类;GaussianNB 的“Gaussian”含义。 |
| 常见错误 | 当作回归模型;忘记它也遵循 fit/predict 接口。 |
3.14 KMeans 聚类#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | KMeans 将样本划分为 K 个簇,通过迭代更新簇中心并最小化样本到中心的距离。 |
| 直观理解 | 先指定 K 个“中心”,把每个点分给最近中心,再不断更新中心位置。 |
| PPT 中对应内容 | PPT 第 54–56 页使用 make_blobs 和 KMeans 演示不同数据分布下的聚类效果。 |
| 老师课堂强调 | KMeans 更适合球形、重叠少、簇数 K 与真实结构接近的数据;如果维度高,可用 PCA 降维后可视化。 |
| 典型例子 | KMeans(n_clusters=3).fit_predict(X) 对二维高斯块数据聚类。 |
| 可能考点 | KMeans 的 K 如何理解;为什么 K 设错会影响结果;KMeans 不适合哪些数据。 |
| 常见错误 | 不标准化;K 乱设;把聚类编号解释为大小顺序;不检查分布形状。 |
3.15 层次聚类#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 层次聚类按照某种准则逐层合并或划分样本,形成层次结构。 |
| 直观理解 | 凝聚聚类从每个样本单独成簇开始,逐步把最近的簇合并;划分聚类则从所有样本一个簇开始逐步拆分。 |
| PPT 中对应内容 | PPT 第 57–61 页介绍 AGNES/DIANA 思想,以及 AgglomerativeClustering 的 Ward、complete、average、single linkage。 |
| 老师课堂强调 | 层次聚类可以呈现中间层次结果;通过树状图观察哪些样本先合并、关系更紧密。具体 linkage 计算不做深入要求,会调用和解释即可。 |
| 典型例子 | 鸢尾花数据做层次聚类并画 dendrogram,从某个距离阈值处“截断”得到若干簇。 |
| 可能考点 | 解释凝聚与划分的区别;理解 dendrogram 横纵轴含义。 |
| 常见错误 | 把层次树的节点距离当作真实空间坐标;忽略不同 linkage 会影响结果。 |
3.16 DBSCAN#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | DBSCAN(Density-Based Spatial Clustering of Applications with Noise) 是一种基于高密度连接区域的密度聚类算法。它不要求用一个簇中心代表整个簇,而是通过邻域密度、核心点和密度可达关系把相互连接的高密度样本组织成簇,并把无法连接到任何簇的样本标为噪声。 |
| 直观理解 | KMeans 像是“每个簇由一个中心代表”,更适合近似球形的簇;DBSCAN 像是“从高密度点出发,沿着密度足够高的邻居不断扩展”,因此可以识别月牙形、环形、蛇形等非球形连续结构。老师用“山峰/山脉”的类比说明:先找到高密度的核心点,再从核心点向外连接,能连成一片的就是一个簇。 |
| PPT 中对应内容 | PPT 第 62–66 页给出 DBSCAN 的基本定义:Eps 是邻居最大半径,MinPts 是核心点最小邻居阈值,,并用图示说明“直接密度可达”。 |
| 老师课堂强调 | 上机补充重点讲了四件事:第一,DBSCAN 是基于邻居、密度、连接的聚类;第二,簇不是由单一中心决定,每个成员及其局部邻居关系都会影响整体形状;第三,eps 描述距离半径,默认欧式距离对特征尺度敏感,所以示例中先用 StandardScaler().fit_transform(X);第四,DBSCAN 相比 KMeans 的重要优势是能把离群点显式标为 -1,且更适合非凸/非球形结构。 |
| 典型例子 | 两个月牙形簇、环形簇或“被咬了一口的面包圈/蛇形”数据,KMeans 往往会按中心距离切分而效果差,DBSCAN 可沿密度连接识别连续簇;孤立点可标为噪声 -1。 |
| 可能考点 | DBSCAN 与 KMeans 的适用场景比较;解释 eps、min_samples、核心点、直接密度可达、噪声点;说明为什么 DBSCAN 前常做标准化;阅读 DBSCAN(eps=0.3, min_samples=10).fit(X) 代码。 |
| 常见错误 | eps 过小导致一个真实簇被切碎,过大导致多个簇合并;min_samples 过大导致噪声点过多;不标准化就用欧式距离聚类;把 -1 当作普通簇;认为 DBSCAN 也需要预先指定簇数 K。 |
标准答题表述:DBSCAN 与 KMeans 的区别:KMeans 是划分式聚类,需要预先给定 K,并用簇中心及样本到中心的距离决定归属,通常更适合球形、尺度相近、噪声较少的数据;DBSCAN 是密度聚类,不需要预先指定簇数,通过 eps 邻域与 min_samples 定义核心点,再根据密度可达关系扩展簇,能识别非球形簇并显式标记噪声点。
3.17 模型评价#
| 维度 | 复习内容 |
|---|---|
| 概念定义 | 模型评价是用指标判断模型表现。不同任务有不同指标:分类看类别判别是否正确、正类识别是否充分;回归看数值误差;聚类看簇内紧凑与簇间分离,或与参考标签的一致程度。 |
| 直观理解 | 模型训练只是“学完了”,评价才是“考一考”。评价时通常把真实标签 y_true 放前面,把预测结果 y_pred 或预测得分 y_score 放后面。 |
| PPT 中对应内容 | PPT 第 68–73 页列出分类、回归、聚类评分函数,并用 SVC 示例计算 accuracy_score、confusion_matrix、roc_curve 与 auc。 |
| 老师课堂强调 | 上机补充强调 sklearn 的评价函数集中在 sklearn.metrics:分类可直接算 accuracy、balanced accuracy、precision、recall、F1、ROC/AUC;回归可算 explained variance、max error、R²、MAE、MSE;聚类指标可作参考,但实际分析中更应结合聚类图、每簇画像和后续业务解释,KMeans 等任务中轮廓系数较常用。 |
| 典型例子 | accuracy_score(y_test, y_pred) 计算准确率;confusion_matrix(y_test, y_pred) 得到 2×2 或多分类计数矩阵;roc_curve(y_test, y_score) 得到 FPR、TPR 和阈值,auc(fpr, tpr) 算 AUC。 |
| 可能考点 | 指标适用任务;混淆矩阵输入顺序;ROC/AUC 需要概率或决策分数;回归 MSE/R² 含义;聚类评价指标只作辅助、不能替代业务解释。 |
| 常见错误 | 分类任务只看 accuracy 而忽略类别不平衡;用硬标签直接画 ROC;把回归任务用 accuracy 评价;把聚类指标当成唯一结论;在没有真实标签的聚类任务中机械套用监督指标。 |
标准答题表述:ROC/AUC 的输入与用途:ROC 曲线用于二分类模型评价,横轴通常为 FPR,纵轴为 TPR,反映不同阈值下假阳性率与真正率的权衡;AUC 是 ROC 曲线下面积,可用于比较模型对正负样本的排序能力。绘制 ROC 通常需要真实标签 y_true 和正类概率/得分 y_score,而不是直接使用 predict 得到的硬分类标签。
4. Python 实现与代码模板#
说明:PPT 展示了若干局部代码。以下模板按课程内容整理为可直接套用版本;未在 PPT 完整展示但符合课程用法的部分标注为“根据课程内容整理的通用模板”。
4.1 通用监督学习流程模板:划分、预处理、训练、评价#
# 根据课程内容整理的通用模板# 输入:X 特征矩阵,y 标签或目标值# 输出:训练好的模型、测试集预测结果、基本评价指标# 用途:分类/回归任务的标准流程
from sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler
# 1. 划分训练集和测试集;分类任务可加 stratify=y 保持类别比例X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y # 回归任务通常去掉 stratify)
# 2. 预处理:只能在训练集 fit,在测试集 transformscaler = StandardScaler()X_train_scaled = scaler.fit_transform(X_train)X_test_scaled = scaler.transform(X_test)
# 3. 建模:替换为具体模型,如 LogisticRegression / LinearRegression / SVC# model = ...# model.fit(X_train_scaled, y_train)# y_pred = model.predict(X_test_scaled)易错点: - 测试集不能 fit_transform,否则会发生数据泄漏或训练/测试转换规则不一致。 - train_test_split 必须同时传入 X 和 y,保证样本与标签同步打乱。 - 回归任务不要使用 stratify=y,因为 y 是连续值。
4.2 StandardScaler 标准化#
# 输入:数值型二维数组 X_train, X_test# 输出:均值约为 0、标准差约为 1 的特征矩阵# 用途:量纲不同、距离/梯度敏感模型前的标准处理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()X_train_std = scaler.fit_transform(X_train) # 训练集:学习均值和标准差,并转换X_test_std = scaler.transform(X_test) # 测试集:使用训练集学到的规则转换
print(scaler.mean_) # 每个特征的训练集均值print(scaler.scale_) # 每个特征的训练集标准差常见报错/易错点: - Expected 2D array:单特征数组需 X.reshape(-1, 1)。 - 测试集重新 fit 会让测试集用自己的均值方差,破坏可比性。
4.3 MinMaxScaler / MaxAbsScaler#
from sklearn.preprocessing import MinMaxScaler, MaxAbsScaler
# MinMaxScaler:把每个特征映射到指定区间,默认 (0, 1)minmax = MinMaxScaler(feature_range=(0, 1))X_train_mm = minmax.fit_transform(X_train)X_test_mm = minmax.transform(X_test)
# MaxAbsScaler:每个特征除以最大绝对值,转换后最大绝对值为 1maxabs = MaxAbsScaler()X_train_ma = maxabs.fit_transform(X_train)X_test_ma = maxabs.transform(X_test)用途:希望保留稀疏性或限定数值区间时使用。 易错点:遇到测试集中超出训练集范围的新值,MinMax 转换后可能超过 [0,1]。
4.4 归一化 Normalizer / normalize#
from sklearn.preprocessing import Normalizer, normalize
# 每个样本向量缩放到单位模长,常用于文本向量空间模型normalizer = Normalizer(norm="l2")X_norm = normalizer.fit_transform(X) # Normalizer 不需要从数据中学习统计量
# 函数式写法X_norm2 = normalize(X, norm="l2")标准化 vs 归一化: - 标准化:按列处理特征分布。 - 归一化:按行处理样本向量长度。
4.5 标称特征编码:OrdinalEncoder 与 OneHotEncoder#
# 输入:类别型特征矩阵,形状通常为二维# 输出:数值矩阵# 用途:将字符串类别转为模型可处理形式
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder
X_cat = [["男", "北京"], ["女", "上海"], ["女", "北京"]]
# OrdinalEncoder:维度不变,但会给类别编码为 0,1,2...ord_enc = OrdinalEncoder()X_ord = ord_enc.fit_transform(X_cat)
# OneHotEncoder:通常升维,每个类别生成一列 0/1onehot = OneHotEncoder(sparse_output=False, handle_unknown="ignore")X_oh = onehot.fit_transform(X_cat)print(onehot.get_feature_names_out())常见报错/易错点: - 旧版 sklearn 参数可能是 sparse=False,新版常用 sparse_output=False。 - 测试集中出现训练集中没有的类别时,如未设置 handle_unknown=“ignore” 可能报错。 - 无序类别不要随便用 OrdinalEncoder,以免引入虚假的大小顺序。
4.6 离散化、二值化#
from sklearn.preprocessing import KBinsDiscretizer, Binarizer
# 分箱:连续值 -> 分箱编号或 one-hot 编码kbd = KBinsDiscretizer(n_bins=4, encode="ordinal", strategy="quantile")X_binned = kbd.fit_transform(X)print(kbd.bin_edges_) # 每个特征的分箱边界
# 二值化:大于阈值记为 1,否则记为 0binz = Binarizer(threshold=0.0)X_binary = binz.fit_transform(X)用途:把连续变量转为类别/区间,便于规则化或某些离散模型处理。 易错点:分箱会损失原始连续信息;阈值应结合业务含义选择。
4.7 多项式特征与交互项#
from sklearn.preprocessing import PolynomialFeatures
# 输入:数值型特征 X# 输出:包含高次项和交互项的新特征矩阵# 用途:增加线性模型表达非线性关系的能力
poly = PolynomialFeatures(degree=2, include_bias=False)X_poly = poly.fit_transform(X)print(poly.get_feature_names_out())
# 只保留交互项,不保留 x1^2、x2^2 等纯高次项poly_inter = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)X_inter = poly_inter.fit_transform(X)易错点:degree 越高,特征数膨胀越快,可能过拟合。
4.8 定制转换器 FunctionTransformer#
# 根据课程内容整理的通用模板# 输入:数值特征矩阵# 输出:经过自定义函数变换后的矩阵# 用途:例如对偏态变量做 log1p 转换
import numpy as npfrom sklearn.preprocessing import FunctionTransformer
log_transformer = FunctionTransformer(np.log1p, validate=True)X_log = log_transformer.fit_transform(X)易错点:对数转换要求输入不能小于 -1;若存在负值,应先平移或使用其他变换。
4.9 分类模板:LogisticRegression#
# 根据课程内容整理的通用模板# 输入:X, y,其中 y 为离散类别# 输出:分类预测、准确率、分类报告
from sklearn.datasets import load_digitsfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, confusion_matrix, classification_report
X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)
scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)
clf = LogisticRegression(max_iter=1000)clf.fit(X_train, y_train)y_pred = clf.predict(X_test)
print("accuracy =", accuracy_score(y_test, y_pred))print(confusion_matrix(y_test, y_pred))print(classification_report(y_test, y_pred))易错点:逻辑回归是分类模型;收敛警告可增大 max_iter 或标准化特征。
4.10 分类模板:DecisionTreeClassifier 与文本规则#
from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.tree import DecisionTreeClassifier, export_textfrom sklearn.metrics import accuracy_score
iris = load_iris()X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)
clf = DecisionTreeClassifier(max_depth=3, random_state=42)clf.fit(X_train, y_train)y_pred = clf.predict(X_test)
print("accuracy =", accuracy_score(y_test, y_pred))print("predict_proba 前 3 行:")print(clf.predict_proba(X_test[:3]))
rules = export_text(clf, feature_names=list(iris.feature_names))print(rules)用途:适合需要解释规则的分类任务。 易错点:max_depth 太大容易过拟合;报告中展示树时建议限制层数。
4.11 回归模板:LinearRegression#
# 对应 PPT diabetes 示例的通用整理版# 输入:数值特征 X,连续目标 y# 输出:预测值、MSE、R^2
from sklearn.datasets import load_diabetesfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LinearRegressionfrom sklearn.metrics import mean_squared_error, r2_score
X, y = load_diabetes(return_X_y=True)X = X[:, [2]] # 只取一个特征,便于画二维图;多特征时可不这样切片
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42)
reg = LinearRegression()reg.fit(X_train, y_train)y_pred = reg.predict(X_test)
print("coef =", reg.coef_)print("intercept =", reg.intercept_)print("MSE =", mean_squared_error(y_test, y_pred))print("R2 =", r2_score(y_test, y_pred))常见报错/易错点:单特征 X 必须是二维,如 X[:, [2]] 或 x.reshape(-1, 1)。
4.12 回归模板:DecisionTreeRegressor 与 max_depth#
from sklearn.tree import DecisionTreeRegressorfrom sklearn.metrics import mean_squared_error, r2_score
reg = DecisionTreeRegressor(max_depth=3, random_state=42)reg.fit(X_train, y_train)y_pred = reg.predict(X_test)
print("MSE =", mean_squared_error(y_test, y_pred))print("R2 =", r2_score(y_test, y_pred))课堂重点:树越深,训练集误差一般越低,但测试集泛化不一定更好。应通过验证集/交叉验证/测试集比较参数。
4.13 朴素贝叶斯分类模板#
from sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import accuracy_score
clf = GaussianNB()clf.fit(X_train, y_train)y_pred = clf.predict(X_test)print("accuracy =", accuracy_score(y_test, y_pred))用途:快速基线分类模型。 易错点:GaussianNB 假设连续特征似然近似高斯分布。
4.14 KMeans 聚类模板#
# 输入:无标签特征矩阵 X# 输出:每个样本的聚类标签、簇中心# 用途:客户细分、样本自动分组
from sklearn.preprocessing import StandardScalerfrom sklearn.cluster import KMeans
scaler = StandardScaler()X_scaled = scaler.fit_transform(X)
kmeans = KMeans(n_clusters=3, random_state=42, n_init="auto")labels = kmeans.fit_predict(X_scaled)
print(labels[:10])print(kmeans.cluster_centers_)易错点: - 课程中强调 KMeans 适合球形、重叠少、K 较合理的数据。 - 聚类编号只是编号,不代表大小或好坏。 - 旧版 sklearn 可能不支持 n_init=“auto”,可改为 n_init=10。
4.15 层次聚类模板#
from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(n_clusters=3, linkage="ward")labels = model.fit_predict(X_scaled)print(labels)根据课程内容整理的 dendrogram 可视化思路: PPT 展示了用层次聚类模型绘制树状图的代码。考试更可能要求理解:横轴是样本,纵轴是合并距离/阈值;从某一高度截断可得到不同簇数。
4.16 DBSCAN 聚类模板#
# 根据 PPT 与上机补充整理的通用模板# 输入:X_raw 为二维特征矩阵,通常需要数值型特征# 输出:每个样本的聚类标签 labels,噪声点标签为 -1# 用途:基于密度的聚类,适合非球形簇、噪声点识别
import numpy as npfrom sklearn.cluster import DBSCANfrom sklearn.preprocessing import StandardScalerfrom sklearn.datasets import make_blobsfrom sklearn import metrics
# 1. 示例数据;真实任务中可替换为自己的 X_rawcenters = [[1, 1], [-1, -1], [1, -1]]X_raw, y_true = make_blobs( n_samples=750, centers=centers, cluster_std=0.4, random_state=0)
# 2. 标准化:DBSCAN 默认常用欧式距离,距离对量纲敏感# 课堂强调:不知道各维度业务权重时,通常先 StandardScalerX = StandardScaler().fit_transform(X_raw)
# 3. 建模与聚类# eps: 邻域半径;min_samples: 成为核心点的最少邻域样本数db = DBSCAN(eps=0.3, min_samples=10).fit(X)labels = db.labels_
# 4. 统计簇数和噪声点数量n_clusters = len(set(labels)) - (1 if -1 in labels else 0)n_noise = np.sum(labels == -1)print("Estimated number of clusters:", n_clusters)print("Estimated number of noise points:", n_noise)
# 5. 如有真实标签,可计算一致性指标;无真实标签时可算 silhouette 作参考if len(set(labels)) > 1 and n_clusters > 1: print("Silhouette Coefficient:", metrics.silhouette_score(X, labels))输入/输出说明: - 输入:X_raw 是原始特征矩阵,行是样本,列是特征。 - 输出:labels 是每个样本的簇标签;-1 表示噪声/离群点。 - 用途:不需要预先指定 K,适合密度结构明显、可能存在离群点的数据。
常见报错与易错点: - 若 eps 太小,可能几乎全是 -1;若太大,多个簇会合并。 - 若不标准化,欧式距离可能被量纲大的变量主导。老师举例说明:身高用厘米、体重用吨时,距离会被数值尺度大的维度主导。 - 真实地理坐标、垄地长度/宽度等物理尺度本身有意义时,不一定机械标准化,应结合业务判断。 - labels 中的 0、1、2 只是编号,没有大小含义。
4.17 分类评价:accuracy、confusion matrix、ROC/AUC#
# 根据 PPT 与上机补充整理的通用模板# 输入:训练好的分类器 clf,测试集 X_test, y_test# 输出:accuracy、混淆矩阵、ROC/AUC 等评价结果# 用途:二分类/多分类基础评价;ROC/AUC 主要面向二分类
from sklearn.metrics import ( accuracy_score, confusion_matrix, classification_report, roc_curve, auc,)
# 1. 预测硬标签y_pred = clf.predict(X_test)print("accuracy =", accuracy_score(y_test, y_pred))print("confusion matrix:\n", confusion_matrix(y_test, y_pred))print(classification_report(y_test, y_pred))
# 2. 二分类 ROC/AUC:需要正类概率或 decision score# 若模型支持 predict_proba:if hasattr(clf, "predict_proba"): y_score = clf.predict_proba(X_test)[:, 1]# 若模型不支持 predict_proba 但支持 decision_function:elif hasattr(clf, "decision_function"): y_score = clf.decision_function(X_test)else: y_score = None
if y_score is not None: fpr, tpr, thresholds = roc_curve(y_test, y_score) roc_auc = auc(fpr, tpr) print("AUC =", roc_auc)易错点: - metrics 函数通常写法是 metric(y_true, y_pred),真实标签在前,预测结果在后。 - ROC/AUC 通常需要正类概率或决策分数,不建议直接用 predict 的硬标签。 - 类别不平衡时,accuracy 可能误导,应同时看 precision、recall、F1 或 balanced accuracy。
4.18 回归评价#
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
print("MAE =", mean_absolute_error(y_test, y_pred))print("MSE =", mean_squared_error(y_test, y_pred))print("R2 =", r2_score(y_test, y_pred))4.19 聚类结果解释模板#
# 根据课程内容整理的通用模板:把聚类标签回写到 DataFrame 后解释import pandas as pd
df_result = df.copy()df_result["cluster"] = labels
# 查看每类样本数量print(df_result["cluster"].value_counts())
# 查看每类特征均值,帮助解释每类画像print(df_result.groupby("cluster").mean(numeric_only=True))答题步骤: 1. 说明使用哪些特征与预处理。 2. 说明选择的聚类算法和参数。 3. 报告每类样本量。 4. 比较每类特征均值/中位数。 5. 给每类命名并解释业务含义。
5. 图表/方法选择指南#
| 遇到的数据/问题 | 应选方法 | 推荐图表/输出 | Python 工具 | 注意事项 |
|---|---|---|---|---|
| y 是“是/否”“A/B/C”等离散类别 | 分类 | 混淆矩阵、分类报告、ROC 曲线(二分类) | LogisticRegression、DecisionTreeClassifier、GaussianNB、SVC | 类别不平衡时不要只看 accuracy |
| y 是房价、温度、销量等连续数值 | 回归 | 真实值 vs 预测值散点图、残差图、MSE/R² | LinearRegression、DecisionTreeRegressor | 回归不使用 accuracy |
| 没有 y,只想自动分组 | 聚类 | 聚类散点图、PCA 降维图、各簇画像表 | KMeans、AgglomerativeClustering、DBSCAN | 聚类标签需业务解释 |
| 特征量纲差异大 | 标准化 | 标准化前后分布比较 | StandardScaler | 训练集 fit,测试集 transform |
| 类别变量是字符串 | 编码 | 编码后特征表 | OneHotEncoder、OrdinalEncoder | 无序类别优先 OneHot |
| 连续变量想转区间 | 分箱/离散化 | 分箱边界、分箱频数表 | KBinsDiscretizer | 会损失连续信息 |
| 需要增加非线性表达能力 | 多项式特征 | 新特征名、交互项 | PolynomialFeatures | degree 过高易过拟合 |
| 样本向量比较方向/相似度 | 归一化 | 单位模长向量 | Normalizer、normalize | 常用于文本向量空间模型 |
| 结构化小数据、需要解释 | 传统 ML/决策树/逻辑回归 | 特征系数、树规则 | LogisticRegression、DecisionTree | 不必直接上深度学习 |
| 球形簇、K 大致已知 | KMeans | 簇中心、二维散点图 | KMeans | K 设错会明显影响效果 |
| 非球形簇、存在噪声 | DBSCAN | 噪声点数量、簇图 | DBSCAN | eps/min_samples 需调参 |
| 想看样本层次关系 | 层次聚类 | dendrogram 树状图 | AgglomerativeClustering、scipy dendrogram | 适合解释哪些样本先合并 |
| 决策树需要报告展示 | 树可视化/文本规则 | export_text 或限深树图 | export_text、export_graphviz | 不要展示过深过宽的树 |
6. 公式与指标总结#
6.1 机器学习映射#
| 项目 | 内容 |
|---|---|
| 公式 | ,新样本预测为 。 |
| 符号含义 | X:输入特征;y:标签/目标;f:由算法从数据中学习到的映射。 |
| 适用条件 | 监督学习,训练数据有 X 和 y。 |
| 直观解释 | 芒果例子中 X 是颜色、大小、形状、产地、品牌;y 是甜度/多汁/成熟度;f 是特征到质量的模型。 |
| 易错点 | 聚类通常没有 y;不要把 f 理解为人工手写规则。 |
6.2 标准化 StandardScaler#
| 项目 | 内容 |
|---|---|
| 公式 | |
| 符号含义 | :训练集该特征均值;:训练集该特征标准差。 |
| 适用条件 | 数值特征;量纲差异明显;距离/梯度敏感模型。 |
| 直观解释 | 把不同单位的特征放到可比较尺度。 |
| 计算步骤 | 训练集计算均值和标准差;训练集和测试集用同一组 转换。 |
| 易错点 | 测试集不能重新计算 。 |
6.3 MinMaxScaler#
| 项目 | 内容 |
|---|---|
| 公式 | 映射到 [0,1];推广到指定区间。 |
| 适用条件 | 希望特征落入固定范围。 |
| 易错点 | 对异常值敏感;测试集新值可能映射到区间外。 |
6.4 Normalization#
| 项目 | 内容 |
|---|---|
| 公式 | L2 归一化: |
| 适用条件 | 文本向量、余弦相似度、样本方向比长度更重要。 |
| 易错点 | 按行处理,不是按列处理。 |
6.5 普通最小二乘 OLS#
| 项目 | 内容 |
|---|---|
| 目标函数 | |
| 预测公式 | |
| 适用条件 | 线性回归基础模型;目标 y 连续。 |
| 直观解释 | 找到使平方误差总和最小的直线/超平面。 |
| 易错点 | X 应为二维;线性关系不足时表现有限。 |
6.6 逻辑回归正则化思想#
| 项目 | 内容 |
|---|---|
| 核心 | 在分类损失上加入 L1、L2 或 Elastic-Net 正则项,控制模型复杂度。 |
| C 参数 | C 越大,正则化越弱,更关注训练拟合;C 越小,正则化越强,更关注泛化。 |
| 适用条件 | 分类任务,尤其是线性可分或近似线性可分的场景。 |
| 易错点 | LogisticRegression 是分类模型。 |
6.7 分类评价指标#
| 指标 | 公式/含义 | 适用场景 | 易错点 |
|---|---|---|---|
| Accuracy 准确率 | 类别较均衡的分类 | 类别不平衡时可能误导 | |
| Precision 精准率 | 关心预测为正的样本有多少真阳性 | 与 recall 容易混淆 | |
| Recall 召回率 | 关心真实正类被找回多少 | 漏报成本高时重要 | |
| F1 | 兼顾 precision 与 recall | 不能反映 TN | |
| Confusion Matrix | 真实类别 vs 预测类别的计数矩阵 | 分类错误结构分析 | 行列含义要看函数约定 |
| ROC/AUC | ROC 展示不同阈值下 TPR/FPR;AUC 为曲线下面积 | 二分类概率排序能力 | 需要概率或得分,不是硬标签 |
6.8 回归评价指标#
| 指标 | 公式/含义 | 适用场景 | 易错点 |
|---|---|---|---|
| MAE | 误差绝对量易解释 | 对大误差不如 MSE 敏感 | |
| MSE | 惩罚大误差 | 单位是 y 的平方 | |
| RMSE | 与 y 同单位 | sklearn 中可由 MSE 开方 | |
| R² | 解释方差比例 | 可为负;不是百分比准确率 |
6.9 KMeans 目标#
| 项目 | 内容 |
|---|---|
| 目标思想 | 最小化样本到所属簇中心的平方距离总和。 |
| 符号含义 | K:簇数;中心点:每簇样本均值;label:样本所属簇编号。 |
| 适用条件 | 簇近似球形、尺度相近、K 可指定。 |
| 易错点 | 不适合明显月牙形、非凸形状或噪声很多的数据。 |
6.10 DBSCAN 核心概念#
| 概念 | 含义 | 易错点 |
|---|---|---|
| eps | 邻域半径 | 过小簇被切碎,过大簇被合并 |
| minPts/min_samples | 成为核心点所需最小邻居数 | 不同实现名称略有差异 |
| 点 p 的 eps 邻域 | 距离度量会影响结果 | |
| 核心点 | 邻域内样本数不少于 minPts 的点 | 是扩展簇的基础 |
| 直接密度可达 | p 在核心点 q 的 eps 邻域内 | 方向性来自 q 是否核心,q 到 p 可达不必然代表 p 到 q 可达 |
| 密度可达 | 经一串直接密度可达关系从核心点扩展到某点 | 可理解为“沿着高密度邻居连过去” |
| 噪声点 | 不属于任何簇的点 | sklearn 标签为 -1,不是普通簇 |
6.11 关联规则指标(不做要求,仅供参考)#
| 指标 | 公式 | 含义 |
|---|---|---|
| Support(X) | #X/n | 包含项集 X 的交易比例 |
| Support(X⇒Y) | #(X∪Y)/n | 同时包含 X 和 Y 的交易比例 |
| Confidence(X⇒Y) | #(X∪Y)/#X = Support(X∪Y)/Support(X) | 在包含 X 的交易中也包含 Y 的比例,可解释为 |
7. 课堂重点与考试提示#
7.1 必背概念#
机器学习 = 用数据/经验让算法在性能指标上改进。关键词:算法、经验、性能。
AI ⊃ ML ⊃ DL。传统机器学习仍适合结构化、小规模、轻量部署、可解释需求较强的任务。
分类、回归、聚类的区别:分类 y 离散;回归 y 连续;聚类没有 y。
机器学习流程:数据清洗 → 特征工程 → 训练/测试 → 训练模型 → 评分评价 → 应用。
标准化和归一化区别:标准化按特征列,归一化按样本行。
LogisticRegression 是分类模型,不是回归模型。
KMeans 适合球形、重叠少、K 合理的数据;DBSCAN 更适合非球形密度结构和噪声点。
DBSCAN 三个关键词:密度、邻居、连接。核心参数是 eps 和 min_samples;噪声点标签为 -1。
模型评价函数真实标签在前、预测结果在后;ROC/AUC 要用概率或得分。
7.2 必会代码#
| 任务 | 必会 API | 标准动作 |
|---|---|---|
| 划分数据 | train_test_split | 同时划分 X 和 y |
| 标准化 | StandardScaler | fit_transform(X_train) + transform(X_test) |
| 分类 | LogisticRegression, DecisionTreeClassifier, GaussianNB | fit + predict + accuracy_score |
| 回归 | LinearRegression, DecisionTreeRegressor | fit + predict + mean_squared_error, r2_score |
| 聚类 | KMeans, AgglomerativeClustering, DBSCAN | fit_predict(X) 或 fit(X).labels_ |
| 决策树解释 | export_text, export_graphviz | 限制深度后展示规则 |
| ROC/AUC | roc_curve, auc | 用概率/得分而不是硬标签 |
7.3 必会分析思路#
分类题答题步骤: 1. 判断 y 是否为离散类别。 2. 说明 X 是哪些特征,y 是什么类别。 3. 划分训练/测试集。 4. 对数值特征标准化,对类别特征编码。 5. 选择分类模型并训练。 6. 用 accuracy、precision、recall、F1、混淆矩阵或 AUC 评价。 7. 解释错误类型和业务含义。
回归题答题步骤: 1. 判断 y 是否连续。 2. 说明特征和目标变量。 3. 划分训练/测试集,必要时标准化。 4. 训练回归模型。 5. 用 MAE/MSE/RMSE/R² 评价。 6. 画真实值 vs 预测值或残差图。 7. 讨论欠拟合/过拟合与参数选择。
聚类题答题步骤: 1. 确认没有标签 y 或目标是探索结构。 2. 选择用于分组的特征。 3. 标准化数值特征。 4. 选择聚类模型:KMeans/层次聚类/DBSCAN。 5. 若使用 DBSCAN,说明 eps、min_samples 的含义,并检查噪声点 -1 的数量。 6. 可视化或降维后可视化。 7. 汇总每类样本数和特征均值。 8. 给出业务解释,说明局限。
7.4 高频易错点#
| 易错点 | 正确做法 |
|---|---|
| 测试集重新 fit_transform | 只在训练集 fit,测试集 transform |
| 只看训练集表现 | 更关注测试集/新样本表现 |
| LogisticRegression 当回归 | 它是分类模型 |
| KMeans 不标准化 | 聚类前通常先标准化 |
| 聚类标签当作有序数值 | 标签只是编号,需要业务解释 |
| 决策树越深越好 | 树太深可能过拟合,应调 max_depth |
| ROC 用 predict 标签 | ROC/AUC 通常用概率或 decision score |
| DBSCAN 前不考虑尺度 | 默认欧式距离对尺度敏感,通常先标准化;但有明确物理尺度时需结合业务判断 |
| DBSCAN 把 -1 当普通簇 | -1 表示噪声点/离群点 |
| OneHot 后维度变化没处理 | 注意输出为多列,可查看特征名 |
| 展示巨大决策树 | 限制 3–4 层或用文本规则 |
| 关联规则当考试重点 | 本讲明确不做要求,仅供参考 |
7.5 可能出题方式#
概念题:解释机器学习三个关键词;解释分类/回归/聚类区别。
判断题:LogisticRegression 是回归模型;聚类需要 y;测试集应重新 fit scaler。
代码阅读题:判断 fit_transform 和 transform 是否用对;判断 predict_proba 输出含义。
代码补全题:补全 sklearn 建模流程、标准化、评价指标。
分析题:给出业务场景,选择分类/回归/聚类并说明理由。
应用题:census_income 数据预处理 + 分类模型比较;预处理后做聚类并解释。
8. 期末复习版精简笔记#
8.1 概念速记#
机器学习:用数据/经验让算法在某个性能指标上变好。
AI、ML、DL:人工智能 ⊃ 机器学习 ⊃ 深度学习。
X、y、f:X 是输入特征,y 是输出标签/目标,f 是从 X 到 y 的映射模型。
流程:清洗 → 特征工程 → 划分训练/测试 → 训练 → 预测 → 评价 → 应用。
局限:很多模型预测能力强,但解释性可能弱。
8.2 三类任务速记#
| 任务 | y | 目标 | 例子 | 模型 |
|---|---|---|---|---|
| 分类 | 离散类别 | 判别属于哪类 | 垃圾邮件、图像识别 | LogisticRegression、DecisionTree、GaussianNB |
| 回归 | 连续数值 | 预测数值多少 | 房价、温度、股价 | LinearRegression、DecisionTreeRegressor |
| 聚类 | 无 y | 自动分组 | 客户细分、异常检测 | KMeans、层次聚类、DBSCAN |
8.3 sklearn 接口速记#
model = ModelName(...)model.fit(X_train, y_train) # 有监督pred = model.predict(X_test)
labels = cluster.fit_predict(X) # 聚类预处理:
scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)8.4 评价指标速记#
分类:accuracy、precision、recall、F1、confusion_matrix、ROC/AUC。
回归:MAE、MSE、RMSE、R²。
聚类:silhouette、ARI、AMI、homogeneity、completeness、V-measure。
8.5 易错一句话#
LogisticRegression 是分类。
测试集只 transform,不 fit。
KMeans 先标准化,K 要合理。
聚类标签没有天然语义。
树越深不一定越好。
AUC 用概率/得分,不是硬标签。
9. 自测题与参考答案
9.1 选择题#
- 机器学习的三个关键词是: A. 数据、图像、网络 B. 算法、经验、性能 C. 训练、绘图、展示 D. 分类、回归、聚类
答案:B。 解析:PPT 明确给出机器学习定义后总结三个关键词:算法、经验、性能。
- 下列哪项最适合用回归模型? A. 判断邮件是否垃圾邮件 B. 判断图片中是猫还是狗 C. 预测房屋成交价格 D. 将客户自动分组
答案:C。 解析:房价是连续数值。A、B 是分类,D 是聚类。
- LogisticRegression 在本课程中主要用于: A. 分类 B. 聚类 C. 降维 D. 关联规则挖掘
答案:A。 解析:老师特别强调不要被 regression 名字迷惑,逻辑回归是分类模型。
- 下列关于 KMeans 的说法正确的是: A. 不需要指定簇数 K B. 适合所有形状的数据 C. 通常更适合球形、重叠少的数据 D. 可以自动识别噪声点为 -1
答案:C。 解析:KMeans 需要指定 K,非球形和噪声多时效果可能差;噪声 -1 是 DBSCAN 常见输出。
- 对测试集进行标准化时,正确做法是: A. scaler.fit_transform(X_test) B. scaler.transform(X_test),其中 scaler 已在训练集 fit C. 测试集不需要标准化 D. 使用测试集均值和方差重新标准化
答案:B。 解析:训练集 fit,测试集 transform,保持转换规则一致。
9.2 判断题#
-
分类任务的 y 通常是离散类别。 答案:对。解析:分类识别对象所属类别。
-
聚类任务通常需要已知标签 y。 答案:错。解析:聚类是无监督学习,通常只传 X。
-
决策树的 max_depth 越大,测试集效果一定越好。 答案:错。解析:max_depth 增大会提高模型复杂度,可能过拟合。
-
StandardScaler 将每个样本缩放到单位模长。 答案:错。解析:StandardScaler 按特征列处理为均值 0、方差 1;单位模长是 Normalizer。
-
关联规则挖掘在本讲属于不做要求内容。 答案:对。解析:课堂转录明确说明本讲和作业不专门要求关联规则。
9.3 简答题#
-
请用标准答题表述解释机器学习。 答案要点:机器学习是通过算法从数据或以往经验中学习规律,并在某一性能指标上自动改进计算机程序表现的方法。核心关键词是算法、经验、性能。
-
分类、回归、聚类有什么区别? 答案要点:分类是有监督学习,目标 y 是离散类别;回归是有监督学习,目标 y 是连续数值;聚类通常是无监督学习,没有标签 y,目标是把相似样本自动分到同一组。
-
为什么传统机器学习仍有价值? 答案要点:深度学习适合复杂数据,但传统机器学习在结构化数据、小规模数据、低算力、轻量部署、可解释需求较强的场景中仍能取得足够好效果,而且更容易理解和部署。
-
数据清洗和特征工程的区别是什么? 答案要点:数据清洗处理错误值、缺失值、异常格式等,使数据可用;特征工程则根据场景、数据和模型特性构造、选择或转换特征,使模型更容易学习有效规律。
-
为什么测试集不能重新 fit scaler? 答案要点:模型建立在训练数据的尺度规则上,测试集应模拟新样本。若测试集重新 fit,会使用测试集自身统计量,导致训练与测试转换规则不一致,也可能产生数据泄漏。
9.4 代码阅读题#
题 1:以下代码有什么问题?如何修改?
scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.fit_transform(X_test)答案:第二个 fit_transform 错,应改为:
X_test = scaler.transform(X_test)解析:测试集必须使用训练集学到的均值和标准差。
题 2:以下模型用于什么任务?
from sklearn.linear_model import LogisticRegressionmodel = LogisticRegression()model.fit(X_train, y_train)y_pred = model.predict(X_test)答案:分类任务。解析:LogisticRegression 虽名为回归,但在 sklearn 中是分类模型。
题 3:以下代码中 labels 的含义是什么?
kmeans = KMeans(n_clusters=3, random_state=42)labels = kmeans.fit_predict(X_scaled)答案:labels 是每个样本所属簇的编号,可能为 0、1、2。编号本身没有大小或业务语义,需要结合各簇特征解释。
9.5 代码补全题#
题 1:补全分类训练与评价代码。
from sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)scaler = StandardScaler()X_train = scaler.____(X_train)X_test = scaler.____(X_test)
clf = LogisticRegression(max_iter=1000)clf.____(X_train, y_train)y_pred = clf.____(X_test)print(accuracy_score(____, ____))答案:
X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)clf.fit(X_train, y_train)y_pred = clf.predict(X_test)print(accuracy_score(y_test, y_pred))题 2:补全回归评价代码。
from sklearn.metrics import mean_squared_error, r2_score
y_pred = reg.predict(X_test)print("MSE =", ____(y_test, y_pred))print("R2 =", ____(y_test, y_pred))答案:mean_squared_error,r2_score。
9.6 数据分析应用题#
题 1:给定 census_income 数据集,最后一列为收入是否 >50K,如何完成分类分析?
标准答题步骤: 1. 明确任务:预测是否 >50K,属于二分类;>50K 为正类,<=50K 为负类。 2. 数据预处理:检查缺失值;对数值特征标准化;对职业、教育、婚姻等标称特征做 OneHot 编码。 3. 划分训练集和测试集,建议使用 stratify 保持正负类比例。 4. 选择至少两个分类模型,如 LogisticRegression 与 DecisionTreeClassifier。 5. 在训练集 fit,在测试集 predict。 6. 用 accuracy、precision、recall、F1、ROC/AUC、混淆矩阵评价。 7. 比较两个模型:不仅看准确率,也要看正类召回、误报漏报和解释性。 8. 给出结论:哪个模型更适合当前目标,可能局限是什么。
题 2:对预处理后的 census_income 特征做聚类,如何解释结果?
标准答题步骤: 1. 明确任务:无监督分组,不使用最后一列收入标签参与聚类;也可后续用收入标签辅助解释。 2. 对数值特征标准化,对类别特征编码。 3. 选择 KMeans、层次聚类或 DBSCAN。 4. 若用 KMeans,尝试不同 K;若维度高,可 PCA 到二维可视化。 5. 将 cluster 标签回写到原表。 6. 统计每簇样本数量、各特征均值/众数、收入比例。 7. 给簇命名,如“高教育高工时群体”“低工时服务业群体”等。 8. 说明局限:聚类编号无天然语义,结果依赖特征选择和标准化方式。
题 3:给一组月牙形二维数据,KMeans 效果不好,应考虑什么方法?为什么?
答案要点:可考虑 DBSCAN。KMeans 偏向球形簇,需要预设 K;月牙形属于非凸/非球形结构,DBSCAN 基于密度连接,能更自然识别连续密集区域,并可标记噪声点。
10. 一页纸考前速览#
10.1 最核心概念#
机器学习:算法 + 经验/数据 + 性能。
AI ⊃ ML ⊃ DL。
X = 特征;y = 标签/目标;f = 学到的映射。
分类:y 离散;回归:y 连续;聚类:无 y 自动分组。
流程:清洗 → 特征工程 → 训练/测试 → fit → predict → evaluate。
10.2 最核心代码#
from sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)model.fit(X_train, y_train)y_pred = model.predict(X_test)labels = KMeans(n_clusters=3, random_state=42, n_init="auto").fit_predict(X_scaled)10.3 模型选择#
| 题目关键词 | 选什么 |
|---|---|
| 是否、类别、垃圾邮件、图像类别 | 分类 |
| 价格、温度、销量、连续数值 | 回归 |
| 自动分组、客户细分、异常点、无标签 | 聚类 |
| 可解释规则 | 决策树 / 逻辑回归 |
| 球形簇、K 已知 | KMeans |
| 非球形簇、噪声点 | DBSCAN |
| 层次结构、样本关系 | 层次聚类 |
10.4 指标选择#
| 任务 | 指标 |
|---|---|
| 分类 | accuracy、precision、recall、F1、confusion matrix、ROC/AUC |
| 回归 | MAE、MSE、RMSE、R² |
| 聚类 | silhouette、ARI、AMI、homogeneity、completeness、V-measure |
10.5 考前最后 10 个易错点#
LogisticRegression 是分类,不是连续值回归。
测试集只 transform,不要 fit_transform。
聚类通常只传 X,没有 y;聚类标签没有大小顺序。
KMeans 要指定 K,且偏好球形、尺度相近、噪声较少的簇。
DBSCAN 的 -1 是噪声点/离群点,不是普通簇。
DBSCAN 的 eps 是邻域半径,min_samples 是核心点最小邻居阈值。
DBSCAN 默认距离受尺度影响,通常先 StandardScaler;但有明确物理尺度时需结合业务判断。
标准化按列,归一化按行;OneHot 会升维,Ordinal 可能引入虚假顺序。
决策树太深会过拟合,报告中树图不要太大。
ROC/AUC 用正类概率或 decision score,metrics 输入通常是真实标签在前;关联规则在本讲不做要求,仅供参考。
附:材料不足或需注意之处#
上机补充已补足 DBSCAN 与模型评价部分,因此本版已将原先“转录未充分覆盖 DBSCAN 后续细节”的说明删除并改写。
PPT 中预处理页列出“推定缺失数据”,但当前 PPT 与转录没有系统展开具体 API;本资料在代码模板中未把缺失值填补作为本讲重点,只在应用题中提示可用缺失值处理。若后续材料补充 SimpleImputer,可再加入。
关联规则挖掘 PPT 保留了支持度、置信度和 Apriori 工具包,上机补充中老师也提到可以选做,但仍不是本讲核心要求;本资料只保留公式附注与低优先级提醒。
上机补充中的若干转录词已按上下文修正:deep scan/DB schedule/DBCI 统一为 DBSCAN,Kevin/KMS/K面子 统一为 KMeans,matrix 统一为 metrics,AOC/LC 统一为 AUC/ROC。
第 7 章 图像数据分析#
内容来源:原文件内容。 课程 PPT《7-图像数据分析-20260518(1).pdf》与 2026-05-18 课堂转录。
1. 本讲/本章知识框架#
本讲的主线是:图像基础知识 → 图像分析应用场景 → 图像数据基本操作 → 具体任务。课堂中老师强调,本讲目标不是深入研究复杂视觉模型,而是理解图像数据是什么,能完成基本图像操作,并能结合机器学习完成简单图像分类任务。
1.1 总体结构#
- 图像基础知识
- 图像与计算机图形学中“图形”的区别
- 图像处理、图像分析、图像理解的层级关系
- 矢量图、位图、灰度图、彩色图
- 像素、通道、分辨率、像素深度、shape
- 图像分析应用场景
- 人脸检测与跟踪、人像美化、人脸聚类
- 真人检测、物体检测、场景识别
- 照片上色、风格迁移、图像描述生成、多模态图文任务
- 图像数据基本操作
- 图像读写:imread / imshow / imsave
- 图像切片:区域访问与通道访问
- 改变大小:resize / rescale
- 旋转与几何变换:rotate
- 对比度调整:is_low_contrast / adjust_gamma / adjust_log
- 颜色直方图:RGB 通道像素值分布
- 具体任务
- 边缘检测:Roberts、Sobel、Scharr、Prewitt、Canny
- 图像分割:像素或区域划分
- 图像识别:人脸、行人、手写数字、车牌
- 图像分类、目标检测、语义分割、实例分割的区别
- 手写数字识别:逻辑回归、SVM、MLP、CNN
- PyTorch 基本流程:Dataset、DataLoader、Model、Loss、Optimizer、Train/Test
2. 核心概念速查表#
| 中文术语 | 英文术语 | 定义 | 适用场景 | 易混点 | 考试可能问法 |
|---|---|---|---|---|---|
| 图像 | Image | 照片、动画、扫描图等形成视觉景象并可被计算机存储处理的数据。 | 图像分析、分类、识别 | 不同于图形;图像通常来自外界采集。 | 简述图像与图形的区别。 |
| 图形 | Graphics | 由几何元素、数学模型或计算机图形学方法生成的视觉对象。 | 矢量绘图、动画建模 | 强调生成机制;本课不研究生成过程。 | 为什么本课主要分析图像而不是图形? |
| 图像处理 | Image Processing | 对像素级数据进行增强、复原、变换等操作,输出常仍是图像。 | 调亮、去噪、旋转、裁剪 | 不要与语义理解混淆。 | 狭义数字图像处理的对象和输出是什么? |
| 图像分析 | Image Analysis | 从图像中提取边缘、区域、颜色、纹理、形状等信息。 | 边缘检测、分割、特征提取 | 与图像理解在深度学习时代边界变模糊。 | 图像处理、分析、理解的抽象层次如何变化? |
| 图像理解 | Image Understanding | 从图像中获得类别、对象、场景等语义知识。 | 分类、识别、描述生成 | 不是单纯像素操作。 | 为什么图像理解数据量反而较小? |
| 矢量图 | Vector Graphics | 用点、线、曲线或方程描述的图。 | 图标、工程图、SVG | 放大不易失真。 | 矢量图和位图放大效果为何不同? |
| 位图 | Bitmap | 用像素值阵列表示的图像。 | 照片、扫描图、视频帧 | 只能直接操作像素,不能天然操作图中物体。 | 位图为什么占用空间较大? |
| 像素 | Pixel | 图像中的最小存储或显示单元。 | 所有位图处理 | 像素不是物体,只是某位置上的数值。 | 像素值如何组成图像? |
| 通道 | Channel | 每个像素的颜色或亮度维度,如 R/G/B/Alpha。 | RGB、RGBA、灰度图 | PNG 可能 4 通道,JPG 通常 3 通道。 | 为什么 PNG 存成 JPG 可能报错? |
| 灰度图 | Grayscale Image | 每个像素通常只有一个亮度值的二维图像。 | 黑白图、边缘检测、医学图像 | shape 通常是二维。 | 灰度图在 Python 中 shape 是什么? |
| 彩色图像 | Color Image | 每个像素由多个颜色通道描述,常见 RGB 三通道。 | 普通照片、识别任务 | Python 中 shape 顺序是 H,W,C。 | 为什么显示尺寸 1920×1080 对应 shape=(1080,1920,3)? |
| 分辨率 | Resolution | 描述图像包含多少像素或单位长度像素密度。 | 文件大小、输入尺寸 | W×H 与 shape 的 H,W 顺序容易混。 | 分辨率越高,文件大小如何变化? |
| 像素深度 | Pixel Depth | 描述单个像素颜色/亮度所需位数或信息量。 | 文件大小估算 | 不同于图像宽高。 | 影响位图大小的因素有哪些? |
| 颜色直方图 | Color Histogram | 统计各通道像素值出现次数。 | 全局颜色特征、检索 | 不保留空间位置。 | 为什么颜色直方图可作为图像特征? |
| 边缘检测 | Edge Detection | 检测图像局部不连续处,常对应区域边界。 | 轮廓分析、特征提取 | 边缘可断裂,不等于目标识别。 | Canny 的 sigma 影响什么? |
| 图像分割 | Image Segmentation | 将像素划分为区域或目标。 | 目标提取、医学影像 | 分割强调区域,边缘检测强调边界。 | 边缘检测和分割有什么区别? |
| 图像分类 | Image Classification | 给整张图一个类别标签。 | 手写数字、猫狗分类 | 不输出目标位置。 | Classification 与 Detection 区别? |
| 目标检测 | Object Detection | 识别对象类别并给出位置框。 | 行人、车辆、人脸检测 | 比分类多了空间定位。 | 为什么检测比分类更复杂? |
| 语义分割 | Semantic Segmentation | 给每个像素分配类别标签。 | 道路、天空、树等像素级分类 | 不区分同类不同实例。 | 语义分割与实例分割区别? |
| 实例分割 | Instance Segmentation | 同时区分类别和同类不同对象。 | 多人、多车场景 | 同类对象要分开编号。 | 两只狗在实例分割中如何标记? |
| CNN | Convolutional Neural Network | 适合图像局部结构数据的前馈神经网络。 | 图像分类、识别、检测 | 核心是局部连接、权重共享、池化。 | CNN 为什么适合图像? |
| Dataset | PyTorch Dataset | 表示可索引的数据集对象。 | 深度学习数据准备 | 负责数据,不负责训练。 | Dataset 和 DataLoader 区别? |
| DataLoader | PyTorch DataLoader | 批量、打乱、并行加载 Dataset。 | 模型训练与测试 | batch size 是每批样本数。 | batch size 有什么作用? |
3. 重点知识详解#
3.1 图像、图形与三层任务:处理—分析—理解#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 图像通常是外界产生或采集的视觉数据;图形更偏计算机图形学,是从数学模型生成可视对象。图像任务可分为图像处理、图像分析、图像理解。 |
| 直观理解 | 图像处理像“修图”;图像分析像“找边、找区域、提特征”;图像理解像“判断图中有什么、是什么场景”。 |
| PPT 对应内容 | PPT 第 3–5 页:图像定义、图像与图形区别、图像处理技术路径。 |
| 课堂强调 | 不研究图像如何生成,而是把外界图像读入 Python 后作为数据对象;深度学习时代分析和理解界限变模糊,端到端模型替代很多人工特征流程。 |
| 典型例子 | 判断一张图中有没有人:原图有大量像素,最终可压缩为 0/1 标签。 |
| 可能考点 | 解释处理、分析、理解的层次;说明传统流程与端到端流程的差异。 |
| 常见错误 | 把图像处理、分析、理解混为一谈;认为图像理解仍只是调亮、裁剪。 |
3.2 矢量图与位图#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 矢量图用几何元素或数学关系表示;位图用像素值矩阵表示。 |
| 直观理解 | 矢量图像“公式”,放大后重新计算仍清晰;位图像“格子”,放大后格子被拉大或插值,容易模糊。 |
| PPT 对应内容 | PPT 第 6–8 页:图像种类、位图定义及文件大小影响因素。 |
| 课堂强调 | 用孔雀图标说明放大后矢量图清晰、位图变糊;课程主要处理照片、扫描图等位图。 |
| 典型例子 | 手机照片、监控视频帧、扫描图片是位图;SVG 图标更接近矢量图。 |
| 可能考点 | 为什么位图文件通常较大?为什么位图放大可能失真? |
| 常见错误 | 认为所有图片放大后效果相同;忽略位图只能直接操作像素。 |
3.3 灰度图、彩色图、通道与 shape#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 灰度图通常用二维数组表示;彩色图通常用三维数组表示,最后一维是通道。 |
| 直观理解 | 灰度图每个像素只描述亮度;RGB 图像每个像素描述红、绿、蓝三个强度。 |
| PPT 对应内容 | PPT 第 10–12 页:灰度图是二维函数 f(x,y),彩色图由三个二维函数组成;skimage 中图像为 np.ndarray。 |
| 课堂强调 | 显示尺寸可能写成 1920×1080,但 Python shape 是 (1080,1920,3),即先高度/行数,再宽度/列数,最后通道。 |
| 典型例子 | 彩色图:(1080,1920,3);灰度图:(1080,1920);RGBA PNG:(H,W,4)。 |
| 可能考点 | 判断图像类型;访问 R/G/B 通道;解释 shape。 |
| 常见错误 | 把 shape 写成 (width,height,channels);忘记灰度图没有第三维。 |
3.4 分辨率、像素深度与文件大小#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 分辨率描述图像像素数量或单位长度像素密度;像素深度描述单个像素所需位数或通道信息量。 |
| 直观理解 | 图像越大、通道越多、每个值占用位数越多,原始数据越大。 |
| PPT 对应内容 | PPT 第 8–9 页:影响位图大小的因素包括分辨率和像素深度。 |
| 课堂强调 | 建模中最常用行列像素数,如 640×480、1920×1080、224×224。 |
| 典型例子 | RGB 图像 1080×1920×3,uint8 原始数据约 6.22 MB。 |
| 可能考点 | 估算图像原始数据大小;解释分辨率越高为何文件越大。 |
| 常见错误 | 只看宽高不看通道;混淆 PPI 与像素总数。 |
3.5 图像读写与格式通道差异#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 图像读写是图像文件与 Python 数组之间的转换。 |
| 直观理解 | imread 把图片变成 ndarray;imshow 显示数组;imsave 保存数组为文件。 |
| PPT 对应内容 | PPT 第 26–27 页:使用 skimage.io 进行读、显示、保存。 |
| 课堂强调 | PNG 可能是四通道,JPG 通常是三通道;把四通道 PNG 直接保存成 JPG 可能报错。转录中的“GPG”应为 JPG,属于语音识别误差。 |
| 典型例子 | road = io.imread(“road.jpg”); io.imsave(“road_copy.jpg”, road)。 |
| 可能考点 | 写出读取、显示、保存图像代码;解释 PNG 保存为 JPG 报错原因。 |
| 常见错误 | 路径错误;保存格式与通道数不匹配;把 imshow 当保存函数。 |
3.6 图像切片、通道访问与局部区域#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 像处理 NumPy 数组一样访问图像局部或通道。 |
| 直观理解 | img[<400>400>,<400>400>,:] 取左上角 400×400 区域;img[:,:,0] 取 R 通道。 |
| PPT 对应内容 | PPT 第 28–29 页:图像读入为 uint8,像素取值 0–255,展示切片访问区域和通道。 |
| 课堂强调 | 每个通道可看作一张二维 feature map;单通道显示时通常用灰度强弱表示该通道值。 |
| 典型例子 | 分别显示校园道路图的 R/G/B 通道,可观察不同通道保留信息差异。 |
| 可能考点 | 判断切片结果 shape;补全代码取局部区域或蓝色通道。 |
| 常见错误 | 通道索引写错;对灰度图使用三维索引。 |
3.7 尺寸变换、缩放与旋转#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 尺寸变换改变图像行列大小;旋转按角度重排或插值像素。 |
| 直观理解 | resize 指定目标尺寸;rescale 指定缩放比例;rotate 指定旋转角度。 |
| PPT 对应内容 | PPT 第 30–35 页:resize、rescale、rotate。 |
| 课堂强调 | 缩放和旋转背后涉及插值,但本课不要求深入掌握插值原理;会调用函数即可。 |
| 典型例子 | 将 (1080,1920,3) 缩小为 (540,960,3);旋转 90° 或 -90°。 |
| 可能考点 | 选择 resize 还是 rescale;解释旋转角度正负方向。 |
| 常见错误 | resize 目标尺寸忘记通道;rescale 版本参数 multichannel/channel_axis 混用。 |
3.8 对比度调整与 gamma#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 对比度调整改变像素亮度分布,使图像更亮、更暗或层次更明显。 |
| 直观理解 | gamma > 1 通常变暗;gamma < 1 通常变亮;gamma = 1 基本不变。 |
| PPT 对应内容 | PPT 第 36–38 页:is_low_contrast、adjust_gamma、adjust_log。 |
| 课堂强调 | 不会 PS 也可以用 Python 调亮/调暗照片;is_low_contrast 可先判断是否低对比度。 |
| 典型例子 | adjust_gamma(img, gamma=0.5) 变亮;gamma=2 变暗。 |
| 可能考点 | 判断 gamma 参数对亮度的影响;写出低对比度判断与调整代码。 |
| 常见错误 | 误以为 gamma 越大越亮;忽略不同函数对像素范围的要求。 |
3.9 颜色直方图#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 统计每个颜色通道中各像素值出现次数。 |
| 直观理解 | 把整张图压缩成 R/G/B 三个分布曲线,用于描述整体颜色特征。 |
| PPT 对应内容 | PPT 第 39 页:绘制颜色直方图。 |
| 课堂强调 | 颜色直方图是早期分类/识别的重要全局特征,牺牲空间位置但保留颜色分布。 |
| 典型例子 | 分别对 img[:,:,0]、img[:,:,1]、img[:,:,2] 做 hist(…, bins=256)。 |
| 可能考点 | 为什么颜色直方图可作为图像特征?它丢失什么信息? |
| 常见错误 | 认为直方图能表示物体位置;忘记 uint8 常见取值 0–255。 |
3.10 边缘检测与 Canny 参数#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 边缘是图像局部特性不连续处,通常对应一个区域结束和另一区域开始。 |
| 直观理解 | 把图中“轮廓线”或局部强变化位置找出来。 |
| PPT 对应内容 | PPT 第 41–45 页:Roberts、Sobel、Scharr、Prewitt、Canny。 |
| 课堂强调 | 感兴趣边缘不等于所有边缘。背景书本、桌缝也有边,但任务可能只关心主体。Canny 的 sigma 小会检测更多杂边,sigma 大更平滑。 |
| 典型例子 | filters.sobel(camera); feature.canny(img, sigma=3)。 |
| 可能考点 | 边缘检测定义;列举常见算子;说明 sigma 影响。 |
| 常见错误 | 把边缘检测当成完整目标识别;认为所有边缘都有任务意义。 |
3.11 分类、检测、语义分割、实例分割#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 分类给整张图标签;检测识别对象并给位置;语义分割给每个像素类别;实例分割还区分同类不同个体。 |
| 直观理解 | 分类回答“是什么”;检测回答“有什么、在哪里”;语义分割回答“每个像素是什么类”;实例分割回答“每个像素属于哪一个具体对象”。 |
| PPT 对应内容 | PPT 第 46–48 页:图像分割、识别与典型任务图示。 |
| 课堂强调 | 边缘检测可能是断裂线,分割强调连续区域;实例分割比语义分割更细。 |
| 典型例子 | 两只狗一只猫:分类给整体标签;检测给三个框;语义分割标狗/猫像素;实例分割区分狗1、狗2、猫。 |
| 可能考点 | 四类视觉任务的区别;根据图示判断任务类型。 |
| 常见错误 | 分类与检测混淆;语义分割与实例分割混淆。 |
3.12 手写数字识别:逻辑回归与系数可视化#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | 将每张 28×28 手写数字图像作为样本,拉平成 784 维向量,用分类模型预测数字标签。 |
| 直观理解 | 每个像素是一个特征;逻辑回归学习每个像素对每个类别的权重。 |
| PPT 对应内容 | PPT 第 49–54 页:MNIST 读取、预处理、逻辑回归训练测试、系数可视化。 |
| 课堂强调 | 拉平成长向量是朴素方法,但会损失空间结构;逻辑回归系数可 reshape 成 28×28 后可视化。 |
| 典型例子 | 10 类分类时,逻辑回归系数 shape 可为 (10,784),每类一组 784 维系数。 |
| 可能考点 | 为什么 reshape?为什么拉平有局限?如何划分训练集和测试集? |
| 常见错误 | 忘记标准化;X 和 y 打乱不同步;系数可视化时没 reshape 回 28×28。 |
3.13 CNN:局部连接、权重共享、池化#
| 维度 | 复习要点 |
|---|---|
| 概念定义 | CNN 是适合图像局部结构数据的前馈神经网络,核心包括局部连接、权重共享、下采样/池化。 |
| 直观理解 | 不立即拉平图像,而是用小窗口在图上滑动,提取边、角、纹理等局部模式,再逐层组合成高级特征。 |
| PPT 对应内容 | PPT 第 55–58 页:前馈神经网络、CNN 及典型结构。 |
| 课堂强调 | 普通全连接/逻辑回归会丢失空间邻接关系;CNN 更适合图像。PyTorch 和 CNN 部分以了解为主。 |
| 典型例子 | 3×3 卷积核扫描局部区域;2×2 最大池化把 4 个值压缩成最大值。 |
| 可能考点 | CNN 为什么适合图像?卷积和池化分别做什么? |
| 常见错误 | 认为 CNN 只是“更多层的逻辑回归”;忽略权重共享降低参数量。 |
4. Python 实现与代码模板#
说明:若 PPT 或课堂只展示了局部代码,下列模板按课程知识整理为可直接套用版本;涉及完整训练流程的代码标注为“根据课程内容整理的通用模板”。
4.1 图像读入、显示与保存#
# 输入:图像文件路径# 输出:np.ndarray 图像数组# 用途:把图像文件读入 Python,显示或保存
from skimage import io
img = io.imread("road.jpg")print(type(img))print(img.dtype)print(img.shape)
io.imshow(img)io.imsave("road_copy.jpg", img)常见错误:路径错误;PNG 可能有 Alpha 通道,直接保存为 JPG 可能报错;保存前注意数组值范围与 dtype。
4.2 查看 shape、dtype、像素范围#
print("shape:", img.shape)print("dtype:", img.dtype)print("min:", img.min())print("max:", img.max())
if img.ndim == 2: print("灰度图:shape = (height, width)")elif img.ndim == 3: print("彩色/多通道图:shape = (height, width, channels)")4.3 图像切片:区域与通道#
# 左上角 400×400 区域part = img[:400, :400, :]
# RGB 三个通道red = img[:, :, 0]green = img[:, :, 1]blue = img[:, :, 2]
import matplotlib.pyplot as pltplt.imshow(red, cmap="gray")plt.title("Red channel")plt.axis("off")plt.show()常见错误:灰度图没有第三维,不能直接使用 img[:, :, 0];RGB 通道索引通常为 0/1/2。
4.4 改变图像大小:resize#
from skimage import transform
# 彩色图 resize:指定 height, width, channelsimg_resized = transform.resize(img, (224, 224, img.shape[2]))print(img_resized.shape) # (224, 224, 3)常见错误:resize 后像素可能变为 float,保存前可用 img_as_ubyte 转回 uint8。
4.5 按比例缩放:rescale#
from skimage import transform
# 新版本 skimage 推荐 channel_axisimg_small = transform.rescale(img, scale=0.5, channel_axis=2)
# 老版本可能使用 multichannel=True 或三元组比例# img_small = transform.rescale(img, (0.5, 0.5, 1))4.6 图像旋转#
from skimage import transform
rot90 = transform.rotate(img, 90) # 通常逆时针 90 度rot_90 = transform.rotate(img, -90) # 通常顺时针 90 度rot45 = transform.rotate(img, 45)4.7 低对比度判断与 gamma 调整#
from skimage import exposure
print(exposure.is_low_contrast(img))
bright = exposure.adjust_gamma(img, gamma=0.5) # 通常变亮dark = exposure.adjust_gamma(img, gamma=2) # 通常变暗same = exposure.adjust_gamma(img, gamma=1) # 基本不变考试记忆:gamma > 1 通常变暗;gamma < 1 通常变亮;gamma = 1 基本不变。
4.8 颜色直方图#
import matplotlib.pyplot as plt
channels = ["Red", "Green", "Blue"]for i, name in enumerate(channels): plt.hist(img[:, :, i].ravel(), bins=256, alpha=0.5, label=name)
plt.xlabel("Pixel value")plt.ylabel("Frequency")plt.legend()plt.show()注意:颜色直方图可作为全局颜色特征,但不保留空间位置信息。
4.9 边缘检测:Sobel 等算子#
from skimage import data, filtersimport matplotlib.pyplot as plt
image = data.camera()edges_roberts = filters.roberts(image)edges_sobel = filters.sobel(image)edges_scharr = filters.scharr(image)edges_prewitt = filters.prewitt(image)
plt.imshow(edges_sobel, cmap="gray")plt.title("Sobel edge")plt.axis("off")plt.show()4.10 Canny 边缘检测#
from skimage import data, feature
image = data.camera()edges_sigma1 = feature.canny(image, sigma=1)edges_sigma3 = feature.canny(image, sigma=3)
# sigma 较小:边缘多,可能有杂边;sigma 较大:更平滑,细节可能减少。课堂重点:sigma 越小通常边缘越多、杂边也可能越多;sigma 越大更平滑但可能丢失细节。
4.11 手写数字识别:sklearn 逻辑回归通用模板#
# 根据课程内容整理的通用模板from sklearn.datasets import load_digitsfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, classification_report
# sklearn 自带 digits 为 8×8;MNIST 思路相同,只是 28×28 -> 784 维digits = load_digits()X = digits.datay = digits.target
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)
scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)
clf = LogisticRegression(max_iter=1000)clf.fit(X_train, y_train)
pred = clf.predict(X_test)print("accuracy:", accuracy_score(y_test, pred))print(classification_report(y_test, pred))4.12 PyTorch 图像分类流程通用模板#
# 根据课程内容整理的通用模板:理解 Dataset/DataLoader/Model/Loss/Optimizer 流程import torchfrom torch import nnfrom torch.utils.data import DataLoaderfrom torchvision import datasetsfrom torchvision.transforms import ToTensor
device = "cuda" if torch.cuda.is_available() else "cpu"
training_data = datasets.FashionMNIST(root="data", train=True, download=True, transform=ToTensor())test_data = datasets.FashionMNIST(root="data", train=False, download=True, transform=ToTensor())
train_loader = DataLoader(training_data, batch_size=64)test_loader = DataLoader(test_data, batch_size=64)
class NeuralNetwork(nn.Module): def __init__(self): super().__init__() self.flatten = nn.Flatten() self.net = nn.Sequential( nn.Linear(28 * 28, 512), nn.ReLU(), nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10) ) def forward(self, x): return self.net(self.flatten(x))
model = NeuralNetwork().to(device)loss_fn = nn.CrossEntropyLoss()optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)4.13 简单 CNN 模板#
# 根据课程内容整理的通用模板:CNN 保留局部空间结构import torchfrom torch import nn
class SimpleCNN(nn.Module): def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 16, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2), # 28×28 -> 14×14 nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2) # 14×14 -> 7×7 ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(32 * 7 * 7, 128), nn.ReLU(), nn.Linear(128, 10) ) def forward(self, x): return self.classifier(self.features(x))易错点:CNN 输入常为 (batch, channel, height, width)。若 Linear 维度报错,应打印卷积输出 shape。
5. 图表/方法选择指南#
| 遇到的问题/数据 | 首选方法 | Python 工具 | 输出结果 | 易错点 |
|---|---|---|---|---|
| 读取图像文件 | 图像读入 | skimage.io.imread | np.ndarray | 检查路径、dtype、shape |
| 显示图像 | 图像显示 | io.imshow / plt.imshow | 图像窗口或绘图区 | 灰度图加 cmap=“gray” |
| 保存图像 | 图像保存 | io.imsave | 图像文件 | 格式与通道数匹配 |
| 取局部区域 | 数组切片 | img[r1 | 局部图像 | 行列顺序别写反 |
| 看 RGB 通道 | 通道切片 | img[:,:,0/1/2] | 单通道图 | 灰度图无第三维 |
| 统一输入尺寸 | 尺寸调整 | transform.resize | 固定大小图像 | 模型输入前常用 |
| 按比例缩放 | 比例缩放 | transform.rescale | 缩放图像 | 注意 channel_axis 版本差异 |
| 调整方向 | 旋转 | transform.rotate | 旋转图像 | 正负角度方向 |
| 图像偏暗/低对比度 | 对比度调整 | exposure.adjust_gamma | 增强图像 | gamma 方向易错 |
| 描述整体颜色 | 颜色直方图 | plt.hist | RGB 分布 | 丢失空间位置 |
| 提取轮廓 | 边缘检测 | filters.sobel / feature.canny | 边缘图 | 边缘不等于目标 |
| 划分区域 | 图像分割 | 分割算法/模型 | 区域或像素标签 | 不同于边缘检测 |
| 整图判类 | 图像分类 | sklearn / CNN | 类别标签 | 不提供目标位置 |
| 找对象位置 | 目标检测 | 检测模型 | 类别 + 边框 | 比分类更复杂 |
| 像素级分类 | 语义分割 | 分割模型 | 像素类别图 | 不区分同类实例 |
| 同类对象区分 | 实例分割 | 实例分割模型 | 类别 + 实例 ID | 比语义分割更细 |
| 简单手写数字分类 | 逻辑回归/SVM/MLP | sklearn | 类别预测 | 拉平会损失空间结构 |
| 利用图像空间结构 | CNN | torch.nn.Conv2d | 类别预测 | 输入维度要正确 |
6. 公式与指标总结#
| 公式/指标 | 表达式或算法思想 | 符号含义、适用条件与易错点 |
|---|---|---|
| 位图原始存储量 | H × W × C × 每通道字节数 | H 为高度,W 为宽度,C 为通道数;uint8 每通道 1 byte。用于估算未压缩像素数据大小。易错:忘记通道数或把 W×H 与 shape 混淆。 |
| 图像 shape | 灰度:(H,W);RGB:(H,W,3);RGBA:(H,W,4) | Python 数组先行后列;系统显示常写宽×高,考试需特别注意顺序。 |
| gamma 调整 | output ≈ input^gamma | 用于亮度/对比度调整。gamma>1 通常变暗,gamma<1 通常变亮。 |
| 颜色直方图 | count(value=k), k=0,…,255 | 分别统计每个通道像素值频数。优点是简单、全局;缺点是不保留空间位置。 |
| 边缘检测思想 | 检测梯度或局部变化较大的位置 | 像素值突变处可能是区域边界。注意边缘可能断裂,也可能包含背景杂边。 |
| 卷积思想 | 局部窗口与卷积核逐元素相乘求和 | 适合提取局部模式,如线条、角点、纹理;权重共享降低参数量。 |
| 最大池化 | 局部窗口取最大值 | 保留局部最强响应并降低空间尺寸;会丢失部分细节。 |
| 分类准确率 | Accuracy = 正确预测数 / 总样本数 | 适合类别较均衡的基础分类任务;类别严重不均衡时可能误导。 |
7. 课堂重点与考试提示#
7.1 必背概念#
- 图像与图形区别
- 位图与矢量图区别
- 灰度图和彩色图的数组表示
- shape=(H,W,C) 的含义
- 像素、通道、分辨率、像素深度
- 图像处理、分析、理解区别
- 分类、检测、语义分割、实例分割区别
- 边缘检测与图像分割区别
- 颜色直方图作为全局特征
- CNN 的局部连接、权重共享、池化
7.2 必会代码#
| 程度 | 代码/知识点 |
|---|---|
| 必会 | io.imread, io.imshow, io.imsave |
| 必会 | img.shape, img.dtype, img.min(), img.max() |
| 必会 | img[<400>400>,<400>400>,:], img[:,:,0] |
| 必会 | transform.resize, transform.rescale, transform.rotate |
| 必会 | exposure.is_low_contrast, exposure.adjust_gamma |
| 必会 | plt.hist(img[:,:,i].ravel(), bins=256) |
| 必会 | filters.sobel, feature.canny |
| 必会 | train_test_split, fit, predict, score |
| 应会 | 将 28×28 图像 reshape / flatten |
| 了解 | PyTorch Dataset、DataLoader、nn.Module、loss.backward、optimizer.step |
7.3 必会分析思路#
图像基础题:判断图像类型 → 说明数组表示 → 解释像素/通道含义 → 说明可进行的基本操作。
图像分类题:读取数据 → 检查 shape/dtype/范围 → 统一尺寸 → 传统方法拉平并标准化,或 CNN 保留二维结构 → 划分训练测试 → 训练模型 → 评价与解释。
视觉任务判断:整图标签是分类;类别+位置框是检测;每像素类别是语义分割;每像素类别+实例编号是实例分割。
7.4 高频易错点#
| 易错点 | 正确理解 |
|---|---|
| shape 顺序 | Python 通常是 H,W,C,不是 W,H,C。 |
| 格式通道 | PNG 可能 4 通道,JPG 通常 3 通道。 |
| 灰度图索引 | 灰度图不能使用 img[:,:,0]。 |
| 像素范围 | uint8 常见为 0–255;resize 后可能变为 0–1 float。 |
| gamma | gamma>1 通常变暗;gamma<1 通常变亮。 |
| 颜色直方图 | 不保留空间位置。 |
| 边缘检测 | 边缘不等于目标,背景也可能有边。 |
| 任务区别 | 分类无位置;检测有框;语义分割不区分同类实例;实例分割区分。 |
| CNN 输入 | PyTorch CNN 常用 (batch, channel, H, W)。 |
7.5 可能出题方式#
- 概念题:解释图像处理、分析、理解的区别。
- 判断题:彩色图在 Python 中 shape 一定是 (width,height,3)。
- 代码阅读题:给出 img[<100>100>,<200>200>,0] 判断结果含义。
- 代码补全题:补全读取图像、gamma 调整、Canny 检测代码。
- 应用题:给一批手写数字图像,说明如何完成分类。
- 分析题:为什么 CNN 比拉平+逻辑回归更适合图像?
- 图示题:判断 Classification / Detection / Semantic Segmentation / Instance Segmentation。
8. 期末复习版精简笔记#
8.1 图像基础#
- 图像 image:外界产生或采集的视觉数据,如照片、视频帧。
- 图形 graphics:由数学模型生成,如矢量图、动画建模。
- 图像处理:像素级操作,输出仍是图像。
- 图像分析:提取边缘、区域、特征。
- 图像理解:获得类别、对象、场景等语义知识。
8.2 类型与 shape#
原文件速记: 矢量图:记录几何关系,放大不易失真。
位图:记录像素值阵列,放大可能模糊。
灰度图:shape = (H, W)
RGB 图:shape = (H, W, 3)
RGBA 图:shape = (H, W, 4)
系统显示 1920×1080;Python shape 通常为 (1080,1920,3)。
8.3 基本代码速记#
from skimage import io, transform, exposure, filters, feature
img = io.imread("road.jpg")io.imshow(img)io.imsave("copy.jpg", img)
img.shapeimg[:400, :400, :]img[:, :, 0]
small = transform.resize(img, (224, 224, 3))rot = transform.rotate(img, 90)bright = exposure.adjust_gamma(img, gamma=0.5)dark = exposure.adjust_gamma(img, gamma=2)edge = filters.sobel(gray_img)edge2 = feature.canny(gray_img, sigma=3)8.4 四类视觉任务#
| 任务 | 输出 |
|---|---|
| Classification | 整张图一个类别 |
| Object Detection | 类别 + 位置框 |
| Semantic Segmentation | 每个像素一个类别 |
| Instance Segmentation | 每个像素类别 + 同类实例编号 |
8.5 手写数字识别#
- 传统方法:28×28 → 784 维向量 → 标准化 → 逻辑回归/SVM/MLP。
- 局限:拉平会损失空间结构。
- 系数可视化:clf.coef_[i].reshape(28,28)。
- CNN:卷积提取局部特征,池化降维,全连接分类。
9. 自测题与参考答案
一、选择题#
-
在 Python 中,一张 RGB 图像 shape 为 (1080,1920,3),下列说法正确的是? A. 宽1080高1920三通道 B. 高1080宽1920三通道 C. 共有1080个通道 D. 一定是 PNG 答案:B。解析:Python 图像数组通常为 (height,width,channels)。
-
关于位图,下列说法错误的是? A. 由像素阵列表示 B. 放大可能模糊 C. 可直接把物体当独立实体操作 D. 大小受分辨率和像素深度影响 答案:C。解析:位图直接存像素值,不能天然把“人”“车”等对象作为独立实体。
-
adjust_gamma(img, gamma=0.5) 通常会使图像: A. 变暗 B. 变亮 C. 通道数变为4 D. 自动灰度化 答案:B。解析:gamma 小于 1 通常变亮。
-
哪个任务只给整张图一个标签? A. Classification B. Detection C. Semantic Segmentation D. Instance Segmentation 答案:A。解析:分类不输出位置或像素标签。
-
颜色直方图最主要丢失的信息是: A. 颜色值范围 B. 通道数量 C. 空间位置 D. 像素频数 答案:C。解析:直方图只统计频数,不知道颜色在哪里。
-
CNN 更适合图像的主要原因是: A. 不需训练 B. 能利用局部空间结构 C. 只能处理灰度图 D. 不需要标签 答案:B。解析:CNN 通过局部连接、权重共享、池化利用图像空间结构。
二、判断题#
-
灰度图通常可以表示为二维数组 (H,W)。 答案:正确。灰度图每个像素通常只有一个亮度值。
-
PNG 图像一定只有 RGB 三个通道。 答案:错误。PNG 可能包含 Alpha 透明通道。
-
图像分割与边缘检测完全等价。 答案:错误。边缘检测找边界,分割划分区域。
-
img[:,:,0] 对灰度图一定可用。 答案:错误。灰度图通常只有二维。
-
目标检测不仅要判断类别,还要给出目标位置。 答案:正确。检测输出类别和边界框。
-
最大池化可以降低特征图空间尺寸。 答案:正确。池化通过局部聚合实现下采样。
三、简答题#
-
简述图像处理、图像分析、图像理解的区别。 参考答案:图像处理主要对像素级数据进行增强、复原、变换等操作,输出通常仍是图像;图像分析从图像中提取边缘、区域、颜色、纹理、形状等信息;图像理解进一步获得类别、对象、场景或描述等语义知识。
-
为什么位图放大后容易模糊,而矢量图不容易? 参考答案:位图记录固定分辨率下的像素值,放大时需要插值,容易模糊或锯齿化;矢量图记录几何关系,可按新尺寸重新计算,因而不易失真。
-
为什么把 28×28 手写数字图像拉平成 784 维向量有局限? 参考答案:拉平保留像素值但弱化二维空间邻接关系;图像识别常依赖局部笔画、线条和角点,CNN 更能利用这些局部结构。
-
说明语义分割和实例分割的区别。 参考答案:语义分割为每个像素分配类别标签,但不区分同类不同对象;实例分割不仅给类别,还区分同类不同个体。
四、代码阅读题#
- 阅读代码并解释 part 和 red 的含义:
img = io.imread("road.jpg")print(img.shape) # (1080, 1920, 3)part = img[:400, :400, :]red = img[:, :, 0]答案:part 是左上角 400×400 的彩色区域,shape 为 (400,400,3);red 是整张图的 R 通道,shape 为 (1080,1920)。
- 判断图像亮度变化:
dark = exposure.adjust_gamma(img, gamma=2)bright = exposure.adjust_gamma(img, gamma=0.5)答案:dark 通常更暗;bright 通常更亮。
- 阅读代码说明模型输入变化:
X = images.reshape(len(images), -1)答案:把每张图像拉平成一维向量,每行一个样本,每列一个像素特征。
五、代码补全题#
| 题目 | 代码片段 | 答案 |
|---|---|---|
| 读取并显示图像 | from skimage import img = io.(“road.jpg”) io.____(img) | io;imread;imshow |
| 取蓝色通道 | blue = img[:, :, ____] | 2 |
| 调整为 224×224 | img_resized = transform.____(img, (224,224,img.shape[2])) | resize |
| Canny 边缘检测 | edges = feature.____(gray_img, sigma=3) | canny |
| 逻辑回归系数可视化 | plt.imshow(coef[0].____(28,28), cmap=“RdBu”) | reshape |
六、数据分析应用题#
- 给定一批手写数字图片,要求用传统机器学习方法完成分类。
答题步骤:读取图像和标签 → 检查 shape/dtype/像素范围 → 统一尺寸 → 拉平成向量 → 标准化 → 划分训练/测试集 → 选择逻辑回归/SVM/MLP → fit 训练 → predict/score 评价 → 可视化或解释模型。
- 给定一张图片,说明如何提取颜色直方图作为特征。
答题步骤:读取图像 → 判断 RGB → 分离 R/G/B 通道 → ravel 拉平 → np.histogram 或 plt.hist 统计 0–255 频数 → 拼接为特征向量 → 输入分类/聚类/检索模型;说明不保留空间位置。
- 街景任务判断:是否道路场景、找行人位置、标每像素类别、标每辆车像素区域。
答案:分别对应图像分类、目标检测、语义分割、实例分割。
- 为什么 CNN 更适合图像识别?
参考答案:图像具有局部空间结构。CNN 使用局部连接提取局部模式,权重共享减少参数并能在不同位置识别相同模式,池化降低维度并保留显著特征,因此比直接拉平+逻辑回归更适合图像识别。
10. 一页纸考前速览#
考前 10 分钟重点看以下内容。
| 模块 | 必须记住的内容 |
|---|---|
| 基础定义 | 图像:外界采集的视觉数据;图形:由数学模型生成。处理:像素级;分析:提取信息;理解:获得语义。 |
| 类型与 shape | 灰度图 (H,W);RGB (H,W,3);RGBA (H,W,4)。系统显示常是 W×H,Python shape 是 H,W,C。 |
| 文件大小 | 原始像素数据 ≈ H×W×C×每通道字节数。分辨率、像素深度、通道数、dtype 都影响大小。 |
| 必会代码 | imread/imshow/imsave;img.shape;img[<400>400>,<400>400>,:];img[:,:,0];resize/rescale/rotate;adjust_gamma;sobel/canny。 |
| gamma | gamma>1 通常变暗;gamma<1 通常变亮;gamma=1 基本不变。 |
| 颜色直方图 | 统计 RGB 各通道 0–255 像素值频数;是全局颜色特征;不保留空间位置。 |
| 边缘 vs 分割 | 边缘检测找局部不连续处,可能断裂;图像分割把像素划分为区域或对象。 |
| 视觉任务 | 分类:整图标签;检测:类别+框;语义分割:每像素类别;实例分割:每像素类别+实例编号。 |
| 手写数字 | 28×28 → 784 维 → 标准化 → 逻辑回归/SVM/MLP。局限:拉平损失空间结构。 |
| CNN | 局部连接、权重共享、池化;输入常为 (batch,channel,H,W)。 |
| 最易错 | H/W 顺序、PNG 四通道、灰度图三维索引、颜色直方图无位置、分类/检测/分割混淆。 |
资料来源:课程 PPT《7-图像数据分析-20260518(1).pdf》与课堂转录《Python数据分析 - 2026-05-18第7-8节 - 孟凡_原文(1).docx》。
第 8 章 文本数据分析基础#
内容来源:原文件内容。 课程 PPT《文本数据分析基础》与 2026-05-25 课堂转录。
1. 本讲/本章知识框架#
1.1 文本/字符串处理基础#
- 字符串的本质
- 字符串是 Python 中除数字外最重要的数据类型之一。
- 字符串可视为有序字符序列,因此可以索引、切片、拼接、重复、成员判断。
- 文本文件、网页内容、用户输入都可视为字符串或字符串集合。
- 通用序列操作
- 索引:s[0], s[-1]
- 分片:s[start:end
] - 加法:字符串拼接
- 乘法:字符串重复
- 成员资格:x in s
- 长度与最值:len, min, max
- 字符串格式化与转义
- 格式化:控制数字、字符串输出形式。
- 转义字符:\n, \t, \, ”, ’ 等。
- 字符串方法
- 测试:isalpha, isdigit, startswith, endswith
- 查找:find, rfind, index, rindex
- 替换:replace
- 拆分:split, partition, splitlines
- 大小写转换:lower, upper, title
- 剥除:strip, lstrip, rstrip
- 正则表达式
- 用规则匹配字符串。
- 基本功能:查找、分组、替换。
- 常用函数:re.search, re.findall, re.finditer, re.sub, re.split, re.match, re.compile
- 常用元字符:\d, \w, \s, ., *, +, ?, {m,n}, ^, $, (…)
1.2 文本数据分析任务#
- 自然语言处理 NLP
- 让机器分析、理解、生成自然语言。
- 难点来自自然语言歧义和背景知识缺失。
- 基础 NLP 任务
- 词性标注
- 词义标注
- 未登录词识别
- 共指分析
- 中文分词
- 中文分词
- 中文没有天然空格,分词是中文文本分析前置步骤。
- 方法:正向最大匹配 FMM、逆向最大匹配 BMM、双向匹配。
- 工具:jieba
- 高层文本分析任务
- 信息抽取
- 命名实体识别 NER
- 实体消歧
- 知识图谱构建
- 自动文摘
- 信息检索
- 情感分析、舆情分析
- 文本表示学习、词嵌入、预训练模型
- 机器翻译、人机对话
1.3 文本可视化分析#
- 基本流程
- 信息收集
- 文本预处理
- 知识表示
- 视觉呈现
- 用户交互
- 典型任务:词云
- 文本读取
- 分词
- 去停用词
- 统计词频
- 设置字体、形状、背景、最大词数等参数
- 绘制与解释
2. 核心概念速查表#
字符串 / String
| 中文术语 | 字符串 |
|---|---|
| 英文术语 | String |
| 定义 | 由字符按顺序组成的不可变序列 |
| 适用场景 | 文本读取、网页内容、用户输入 |
| 易混点 | 字符串不可原地修改,方法通常返回新字符串 |
| 考试可能问法 | 为什么字符串可以索引和切片? |
序列 / Sequence
| 中文术语 | 序列 |
|---|---|
| 英文术语 | Sequence |
| 定义 | 有顺序、可索引的数据结构 |
| 适用场景 | 字符串、列表、元组 |
| 易混点 | 集合无顺序,不是序列 |
| 考试可能问法 | 字符串、列表、集合哪些是序列? |
索引 / Indexing
| 中文术语 | 索引 |
|---|---|
| 英文术语 | Indexing |
| 定义 | 用位置访问序列元素 |
| 适用场景 | 取字符、取列表元素 |
| 易混点 | 正向从 0 开始,负向从 -1 开始 |
| 考试可能问法 | s[-1] 返回什么? |
切片/分片 / Slicing
| 中文术语 | 切片/分片 |
|---|---|
| 英文术语 | Slicing |
| 定义 | 从序列中提取子序列 |
| 适用场景 | 提取扩展名、截取文本片段 |
| 易混点 | 左闭右开:s[a] 不含 b |
| 考试可能问法 | 写代码提取文件扩展名 |
成员资格 / Membership
| 中文术语 | 成员资格 |
|---|---|
| 英文术语 | Membership |
| 定义 | 判断元素是否在序列中 |
| 适用场景 | 判断字符/词是否出现 |
| 易混点 | 对字符串是子串判断 |
| 考试可能问法 | ’py’ in ‘python’ 结果? |
转义字符 / Escape Character
| 中文术语 | 转义字符 |
|---|---|
| 英文术语 | Escape Character |
| 定义 | 用反斜线表示特殊字符 |
| 适用场景 | 换行、制表、引号输出 |
| 易混点 | \n 是换行,不是两个字符 |
| 考试可能问法 | 如何输出反斜线? |
字符串测试方法 / String Test Methods
| 中文术语 | 字符串测试方法 |
|---|---|
| 英文术语 | String Test Methods |
| 定义 | 判断字符串是否满足某条件 |
| 适用场景 | 数据清洗、字段校验 |
| 易混点 | isdigit, isnumeric, isdecimal 范围不同 |
| 考试可能问法 | 如何判断字符串是否全为数字? |
find / find
| 中文术语 | find |
|---|---|
| 英文术语 | find |
| 定义 | 查找子串,找不到返回 -1 |
| 适用场景 | 安全查找 |
| 易混点 | 与 index 的异常行为不同 |
| 考试可能问法 | find 与 index 区别 |
index / index
| 中文术语 | index |
|---|---|
| 英文术语 | index |
| 定义 | 查找子串,找不到报 ValueError |
| 适用场景 | 确定子串必然存在时 |
| 易混点 | 不适合直接处理脏数据 |
| 考试可能问法 | 找不到时会怎样? |
split / split
| 中文术语 | split |
|---|---|
| 英文术语 | split |
| 定义 | 按分隔符拆成列表 |
| 适用场景 | CSV、日志、文本清洗 |
| 易混点 | 连续空白用正则 \s+ 更稳 |
| 考试可能问法 | 如何按空白拆分字符串? |
strip / strip
| 中文术语 | strip |
|---|---|
| 英文术语 | strip |
| 定义 | 删除首尾指定字符 |
| 适用场景 | 去空格、去换行、去标点 |
| 易混点 | 参数是“字符集合”,不是完整子串 |
| 考试可能问法 | strip(‘ab’) 删除什么? |
正则表达式 / Regular Expression / Regex / RE
| 中文术语 | 正则表达式 |
|---|---|
| 英文术语 | Regular Expression / Regex / RE |
| 定义 | 用字符串规则描述一类字符串模式 |
| 适用场景 | 校验、抽取、替换、切分 |
| 易混点 | 不是普通字符串查找,而是模式匹配 |
| 考试可能问法 | 正则表达式三大基本功能? |
re.findall / find all matches
| 中文术语 | re.findall |
|---|---|
| 英文术语 | find all matches |
| 定义 | 返回所有匹配结果列表 |
| 适用场景 | 提取所有词、日期、代码 |
| 易混点 | 不返回位置信息 |
| 考试可能问法 | 提取所有日期 |
re.search / search
| 中文术语 | re.search |
|---|---|
| 英文术语 | search |
| 定义 | 返回第一个匹配对象 |
| 适用场景 | 判断是否存在并取位置 |
| 易混点 | 与 match 不同,search 不要求行首 |
| 考试可能问法 | search 返回值怎么取匹配内容? |
re.finditer / find iterator
| 中文术语 | re.finditer |
|---|---|
| 英文术语 | find iterator |
| 定义 | 返回所有匹配对象迭代器 |
| 适用场景 | 需要内容和位置 |
| 易混点 | 比 findall 信息更全 |
| 考试可能问法 | 如何同时得到所有匹配及位置? |
re.sub / substitute
| 中文术语 | re.sub |
|---|---|
| 英文术语 | substitute |
| 定义 | 用新字符串替换匹配内容 |
| 适用场景 | 批量清洗、格式转换 |
| 易混点 | 参数顺序:模式、新值、原字符串 |
| 考试可能问法 | 把多个空白替换为逗号 |
修饰符 / Flag / Modifier
| 中文术语 | 修饰符 |
|---|---|
| 英文术语 | Flag / Modifier |
| 定义 | 控制匹配方式 |
| 适用场景 | 忽略大小写、多行匹配 |
| 易混点 | re.I 表示忽略大小写 |
| 考试可能问法 | 如何让 python 匹配 PYTHON? |
分组 / Grouping
| 中文术语 | 分组 |
|---|---|
| 英文术语 | Grouping |
| 定义 | 用括号捕获子模式 |
| 适用场景 | 日期重排、结构化抽取 |
| 易混点 | \1, \2 引用分组 |
| 考试可能问法 | 如何把 15/09/2018 转为 2018-09-15? |
NLP / Natural Language Processing
| 中文术语 | NLP |
|---|---|
| 英文术语 | Natural Language Processing |
| 定义 | 机器处理自然语言的技术领域 |
| 适用场景 | 分词、翻译、问答、摘要 |
| 易混点 | NLP 不等于单纯字符串处理 |
| 考试可能问法 | 为什么 NLP 难? |
词性标注 / Part-of-Speech Tagging
| 中文术语 | 词性标注 |
|---|---|
| 英文术语 | Part-of-Speech Tagging |
| 定义 | 给词标注名词、动词等语法类别 |
| 适用场景 | 句法分析、信息抽取 |
| 易混点 | 依赖分词结果 |
| 考试可能问法 | 什么是词性标注? |
词义标注 / Word Sense Disambiguation
| 中文术语 | 词义标注 |
|---|---|
| 英文术语 | Word Sense Disambiguation |
| 定义 | 判断词在上下文中的具体含义 |
| 适用场景 | 翻译、搜索、问答 |
| 易混点 | 同形异义、同词性异义、近义都可能混淆 |
| 考试可能问法 | bank 为什么难处理? |
未登录词 / Out-of-Vocabulary Word / OOV
| 中文术语 | 未登录词 |
|---|---|
| 英文术语 | Out-of-Vocabulary Word / OOV |
| 定义 | 词典中没有的新词、专名、缩略语 |
| 适用场景 | 中文分词、NER |
| 易混点 | 不是拼写错误,而是词库未收录 |
| 考试可能问法 | 为什么品牌名、新词难识别? |
共指分析 / Coreference Resolution
| 中文术语 | 共指分析 |
|---|---|
| 英文术语 | Coreference Resolution |
| 定义 | 判断“他/它/该公司”等指代谁 |
| 适用场景 | 文本理解、信息抽取 |
| 易混点 | 需要上下文和常识 |
| 考试可能问法 | 句中“他”指谁? |
中文分词 / Chinese Word Segmentation
| 中文术语 | 中文分词 |
|---|---|
| 英文术语 | Chinese Word Segmentation |
| 定义 | 将无空格中文文本切分为词 |
| 适用场景 | 中文 NLP 前处理 |
| 易混点 | 分词错误会传递到后续任务 |
| 考试可能问法 | 为什么中文要分词? |
正向最大匹配 / Forward Maximum Matching / FMM
| 中文术语 | 正向最大匹配 |
|---|---|
| 英文术语 | Forward Maximum Matching / FMM |
| 定义 | 从左到右按最长词匹配 |
| 适用场景 | 规则分词 |
| 易混点 | 容易局部最优 |
| 考试可能问法 | FMM 如何切“研究生命的起源”? |
逆向最大匹配 / Backward Maximum Matching / BMM
| 中文术语 | 逆向最大匹配 |
|---|---|
| 英文术语 | Backward Maximum Matching / BMM |
| 定义 | 从右到左按最长词匹配 |
| 适用场景 | 中文规则分词 |
| 易混点 | 通常较 FMM 好,但不绝对 |
| 考试可能问法 | 为什么 BMM 有时更准确? |
停用词 / Stop Words
| 中文术语 | 停用词 |
|---|---|
| 英文术语 | Stop Words |
| 定义 | 高频但区分度低的词 |
| 适用场景 | 词频统计、词云、检索 |
| 易混点 | 不是所有高频词都有分析价值 |
| 考试可能问法 | 为什么要去停用词? |
词嵌入 / Word Embedding
| 中文术语 | 词嵌入 |
|---|---|
| 英文术语 | Word Embedding |
| 定义 | 将词表示为向量 |
| 适用场景 | 语义相似度、机器学习 |
| 易混点 | 不是简单编号,而是语义向量 |
| 考试可能问法 | “嵌入”是什么意思? |
预训练模型 / Pre-trained Model
| 中文术语 | 预训练模型 |
|---|---|
| 英文术语 | Pre-trained Model |
| 定义 | 在大规模语料上先训练的模型 |
| 适用场景 | BERT、文本分类、问答 |
| 易混点 | 预训练不等于直接完成所有任务 |
| 考试可能问法 | BERT 的两个预训练任务是什么? |
词云 / Word Cloud
| 中文术语 | 词云 |
|---|---|
| 英文术语 | Word Cloud |
| 定义 | 用词大小展示词频或权重 |
| 适用场景 | 快速展示文本主题 |
| 易混点 | 好看但不等于严谨统计分析 |
| 考试可能问法 | 词云绘制步骤有哪些? |
3. 重点知识详解#
3.1 字符串是有序、不可变的聚合数据结构#
概念定义:字符串是由字符按顺序组成的序列。由于它是序列,因此支持索引、切片、遍历、长度计算和成员判断。
直观理解:“apple” 可以看成 5 个字符排成一列:a p p l e。正向索引是 0,1,2,3,4,反向索引是 -5,-4,-3,-2,-1。
PPT 中对应内容:PPT 将字符串、列表、元组统一归为序列,并展示了 “APPLE” 的正负索引图。
老师课堂强调:老师强调字符串可像列表一样索引和切片,可以从长文本中抽取子串;集合没有顺序,所以不是序列。
典型例子:
s = "apple"print(s[0]) # aprint(s[-1]) # eprint(s[::-1]) # elppa可能考点:判断哪些对象是序列;根据索引写输出结果;用切片反转字符串。
常见错误:把 s[1<3>3>] 误以为包含第 3 位;忘记字符串不可变,不能写 s[0] = ‘A’。
3.2 索引、切片与文件扩展名提取#
概念定义:切片用于从序列中提取连续或间隔的子序列。形式为:
原文件提示: s[start:end
]
其中 start 包含,end 不包含。
直观理解:切片像用刀从字符串中切出一段,end 是“切到这里为止”,不包括这个位置本身。
PPT 中对应内容:PPT 用 get_ext(fname) 示例返回文件名扩展名,通过 rfind(’.’) 找最右侧的点。
老师课堂强调:老师解释 rfind 的 r 是 right,即从右侧找。对于 pizza.old.py,必须找最右边的 .,否则会误把 old.py 当成扩展名。
典型例子:
def get_ext(fname): """返回文件扩展名;没有扩展名则返回空字符串""" dot = fname.rfind(".") if dot == -1: return "" return fname[dot + 1:]print(get_ext("hello.text")) # textprint(get_ext("pizza.py")) # pyprint(get_ext("pizza.old.py")) # pyprint(get_ext("pizza")) # ''可能考点:写函数提取扩展名;解释为什么用 rfind 而不是 find;判断无点文件名时返回什么。
常见错误:写成 fname[dot:],导致结果包含 .;不处理 dot == -1,导致无扩展名时逻辑错误。
3.3 字符串拼接、重复与 join#
概念定义:+ 拼接字符串;* 重复字符串;join 用指定分隔符连接多个字符串。
直观理解:+ 是把两段文本首尾相接,join 是在一组字符串中间插入分隔符。
PPT 中对应内容:PPT 展示 “Hello, ” + “world!” 和 ”-“.join(seq)。
老师课堂强调:老师指出 join 是 Python 文本处理中很常见的方法。如果有 6 个字符串,用分隔符连接时中间会出现 5 个分隔符。
典型例子:
words = ["r", "u", "n", "o", "o", "b"]print("-".join(words)) # r-u-n-o-o-bprint("".join(words)) # runoobprint("Python" * 3) # PythonPythonPython可能考点:join 的调用对象是谁;判断 join 输出中分隔符数量。
常见错误:写成 words.join(”-”);对非字符串列表直接 join,如 [“a”, 1] 会报错。
3.4 字符串查找:find 与 index#
概念定义:find(t) 找到返回起始位置,找不到返回 -1;index(t) 找到返回起始位置,找不到抛出 ValueError;rfind / rindex 从右向左查找。
直观理解:find 更适合处理不确定是否存在的脏数据;index 更适合你确信目标存在的场景。
PPT 中对应内容:PPT 明确区分 index 和 find 的差异:找不到时,index 报错,find 返回 -1。
老师课堂强调:老师强调实际文本中可能有多个目标,要注意从左找还是从右找、找第一个还是找最后一个。
典型例子:
s = "www.google.com"print(s.find(".")) # 3print(s.rfind(".")) # 10print(s.find("@")) # -1可能考点:find 与 index 区别;rfind 在提取扩展名、域名后缀中的作用。
常见错误:用 index 处理未知文本导致程序中断;忘记判断 find 的 -1。
3.5 字符串拆分、剥除与清洗#
概念定义:split(t) 按分隔符拆分为列表;partition(t) 拆成 (head, t, tail) 三部分;strip(ch) 从字符串首尾删除 ch 中包含的字符;replace(old, new) 替换字符串中的旧子串。
直观理解:文本数据常常“不干净”:有多余空格、制表符、换行符、标点。清洗的目标是把格式标准化。
PPT 中对应内容:PPT 列出字符串替换函数、拆分函数、剥除函数。
老师课堂强调:老师特别强调,实际 CSV 或不同系统导出的数据可能存在分隔符混乱、空白符不统一、字段中含逗号等问题。处理文本数据时,要先想清楚分隔规则和清洗规则。
典型例子:
url = "www.google.com"print(url.partition(".")) # ('www', '.', 'google.com')print(url.rpartition(".")) # ('www.google', '.', 'com')print(url.split(".")) # ['www', 'google', 'com']s = " \n\tHello Python\t\n "print(s.strip()) # Hello Python可能考点:partition 与 split 的返回值差异;strip 只处理首尾,不处理中间;对混合空白符使用正则更稳。
常见错误:误以为 strip(“abc”) 删除字符串 “abc”,实际删除首尾所有属于 {a,b,c} 的字符;误以为 replace 会修改原字符串,实际返回新字符串。
3.6 正则表达式:规则化字符串处理#
概念定义:正则表达式是用一个模式字符串描述一类字符串规则的工具。核心功能是查找、分组、替换。
直观理解:普通查找是“找一个固定词”;正则是“找符合某种模式的一类东西”。例如 \d{6} 可以匹配任意 6 位数字,而不需要列举所有股票代码。
PPT 中对应内容:PPT 讲到正则可用于手机号、身份证号、邮箱、密码、域名、IP、URL 等输入校验,也可获取网页中的股票代码,并列出常用 re 函数。
老师课堂强调:老师反复说明,系统不可能存储世界上所有合法手机号或身份证号,而是通过规则判断输入是否合法。课堂还举了预约系统、QQ 注册密码、股票代码、Word/WPS 批量替换等例子。
典型例子:
import reline = "JAVA PHP Python C++ Perl SQL"pattern = r"\w+"print(re.findall(pattern, line))# ['JAVA', 'PHP', 'Python', 'C', 'Perl', 'SQL']可能考点:正则表达式定义;正则三大功能;findall/search/sub/split/finditer 的用途;\w+ 为什么不能完整匹配 C++。
常见错误:忘记使用原始字符串 r”…”;把 . 当普通点号使用,未转义;不理解 findall 与 finditer 返回值差异。
3.7 正则函数:查找、替换、切分、位置获取#
re.findall(pattern, line) / 找所有匹配
| 函数 | re.findall(pattern, line) |
|---|---|
| 作用 | 找所有匹配 |
| 返回值 | 列表 |
| 适合场景 | 只要匹配内容 |
| 易错点 | 不返回位置 |
re.search(pattern, line) / 找第一个匹配
| 函数 | re.search(pattern, line) |
|---|---|
| 作用 | 找第一个匹配 |
| 返回值 | 匹配对象或 None |
| 适合场景 | 判断存在并取位置 |
| 易错点 | 需要先判断是否为 None |
re.finditer(pattern, line) / 找所有匹配对象
| 函数 | re.finditer(pattern, line) |
|---|---|
| 作用 | 找所有匹配对象 |
| 返回值 | 迭代器 |
| 适合场景 | 需要内容、起止位置 |
| 易错点 | 需循环取值 |
re.sub(pattern, new, line) / 替换
| 函数 | re.sub(pattern, new, line) |
|---|---|
| 作用 | 替换 |
| 返回值 | 新字符串 |
| 适合场景 | 清洗、格式转换 |
| 易错点 | 参数顺序别写反 |
re.split(pattern, line) / 正则切分
| 函数 | re.split(pattern, line) |
|---|---|
| 作用 | 正则切分 |
| 返回值 | 列表 |
| 适合场景 | 按复杂分隔符切分 |
| 易错点 | 连续空白应用 \s+ |
re.match(pattern, line) / 从行首匹配
| 函数 | re.match(pattern, line) |
|---|---|
| 作用 | 从行首匹配 |
| 返回值 | 匹配对象或 None |
| 适合场景 | 检查开头 |
| 易错点 | 与 search 不同 |
典型模板:
import reline = "order date: 31-08-2019 delivery date: 15-09-2019"pattern = r"\d{1,2}-\d{1,2}-\d{4}"m = re.search(pattern, line)if m: print(m.group()) # 匹配内容 print(m.span()) # 起止位置 print(m.start(), m.end())for m in re.finditer(pattern, line): print(m.group(), m.span())可能考点:group, span, start, end 的作用;search 只返回第一个匹配;获取所有匹配位置应使用 finditer。
3.8 正则分组与日期格式重排#
概念定义:用小括号 (…) 捕获分组,然后用 \1, \2, \3 引用分组内容。
直观理解:把原字符串拆成几块,再按新顺序重组。
PPT 中对应内容:PPT 示例将 15/09/2018 18<17>17> 转换为 2018-09-15 18<17>17>。
老师课堂强调:老师强调每个小括号就是一个分组,new = r’\3-\2-\1 \4:\5’ 是把第三组、第二组、第一组、第四组、第五组重新排列。
典型例子:
import reline = "15/09/2018 18:17"pattern = r"(\d{2})/(\d{2})/(\d{4}).*(\d{2}):(\d{2})"new = r"\3-\2-\1 \4:\5"print(re.sub(pattern, new, line))# 2018-09-15 18:17可能考点:分组编号从左到右;.* 表示除换行外任意字符重复 0 次或多次;\3-\2-\1 的含义。
常见错误:忘记加 r,导致 \1 被 Python 字符串转义机制干扰;分组数量和引用编号不对应。
3.9 中文分词与最大匹配算法#
概念定义:中文分词是把连续中文字符序列切分为词序列。由于中文没有天然空格,分词是中文文本分析的重要预处理步骤。
直观理解:“研究生命的起源”到底切成“研究 / 生命 / 的 / 起源”,还是“研究生 / 命 / 的 / 起源”?不同切法会导致完全不同的语义。
PPT 中对应内容:PPT 介绍 FMM、BMM、长词优先原则,并给出“研究生命的起源”的正向和逆向匹配示例。
老师课堂强调:老师详细讲了该例子:正向最大匹配会先匹配出“研究生”,结果明显错误;逆向从后往前匹配,往往更准确,但“不一定”总是更好。
FMM 正向最大匹配 / 左到右
| 方法 | FMM 正向最大匹配 |
|---|---|
| 方向 | 左到右 |
| 核心规则 | 每次取当前起点后最长候选词 |
| 优点 | 简单、直观 |
| 局限 | 容易受前部歧义影响 |
BMM 逆向最大匹配 / 右到左
| 方法 | BMM 逆向最大匹配 |
|---|---|
| 方向 | 右到左 |
| 核心规则 | 每次从右端取最长候选词 |
| 优点 | 中文中常更准 |
| 局限 | 仍依赖词典 |
双向匹配 / 两边都做
| 方法 | 双向匹配 |
|---|---|
| 方向 | 两边都做 |
| 核心规则 | 比较 FMM/BMM 结果 |
| 优点 | 可减少局部错误 |
| 局限 | 仍不能完全解决歧义 |
分词原则:颗粒度越大越好;非词典词越少越好;单字词越少越好;总体词数越少越好。
可能考点:解释中文为什么需要分词;手算 FMM/BMM;判断哪个分词结果更合理;说明最大匹配法的问题。
常见错误:认为逆向最大匹配一定正确;忽略词典对结果的决定性影响;把“长词优先”理解为语义一定正确。
3.10 jieba 分词#
概念定义:jieba 是常用中文分词工具,支持精确模式、全模式、搜索引擎模式。
PPT 中对应内容:PPT 给出 jieba.cut 和 jieba.cut_for_search 示例。
老师课堂强调:老师提到 jieba 的词库也有限,如“北京大学信息管理系”可能被切成“北京大学 / 信息管理 / 系”,说明工具输出不是绝对正确。
典型例子:
import jiebatext = "我来到北京大学信息管理系"# 精确模式:适合文本分析seg_list = jieba.cut(text, cut_all=False)print("/ ".join(seg_list))# 全模式:列出所有可能词,冗余较多seg_list = jieba.cut(text, cut_all=True)print("/ ".join(seg_list))# 搜索引擎模式:适合检索seg_list = jieba.cut_for_search("李彦宏本科毕业北京大学信息管理系")print(", ".join(seg_list))可能考点:三种模式区别;为什么分词前要去标点、数字、拉丁字母、闭锁词、停用词;分词错误对后续词频、词云、情感分析的影响。
3.11 NLP 难点:歧义与知识体系缺乏#
概念定义:文本数据分析的核心难点是自然语言中的歧义现象。机器缺少人类常识、背景知识和场景理解,因此很难准确理解文本。
PPT 中对应内容:PPT 提到“大胜/大败”、valuable/invaluable、酒店翻译机误译、“How can I help you?” 等例子。
老师课堂强调:老师强调机器理解语言难,是因为很多问题不只靠语言本身,还要靠语言之外的知识。限定领域、引入知识库、训练数据和规则都有助于降低难度。
典型例子:book 可以是名词“书”,也可以是动词“预定”;bank 可以是“银行”,也可以是“河岸”;“材料”可指文字材料、建筑材料,也可指“某人适合某工作”。
可能考点:为什么 NLP 难;举例说明歧义;说明规则方法和经验方法的差异。
常见错误:认为大模型出现后 NLP 难点完全消失;忽略领域知识在具体任务中的作用。
3.12 信息抽取、知识图谱与文本表示学习#
信息抽取:从非结构化文本中抽取结构化字段,如事件、时间、地点、死亡人数、失踪人数。
命名实体识别 NER:识别人名、地名、机构名、疾病名、蛋白质名等实体。
实体消歧:判断同一个名称在真实世界中指向哪个实体。
知识图谱:由实体和实体关系构成的结构化知识网络。构建通常需要实体识别、实体消歧、关系抽取。
文本表示学习:将词、句子或文档转化为向量,使其可计算、可比较。课堂中老师强调“嵌入”说白了就是把文本变成向量。
可能考点:信息抽取与知识图谱的关系;词嵌入为什么能让文本“可计算”;Word2Vec、BERT 的基本含义;BERT 的预训练任务:Masked Language Model 与 Next Sentence Prediction。
4. Python 实现与代码模板#
4.1 字符串基础操作模板#
# 输入:字符串 s# 输出:索引、切片、反转、成员判断等结果# 用途:处理字符串中的字符或子串s = "apple"# 1. 索引first_char = s[0] # 第一个字符:'a'last_char = s[-1] # 最后一个字符:'e'# 2. 切片sub = s[1:4] # 'ppl',左闭右开reverse_s = s[::-1] # 'elppa'# 3. 成员判断has_app = "app" in s # True# 4. 长度n = len(s) # 5常见报错/易错点:IndexError: string index out of range 表示索引超出范围;字符串不可变,不能写 s[0] = ‘A’。
4.2 提取文件扩展名模板#
# 输入:文件名 fname# 输出:扩展名;若无扩展名返回空字符串# 用途:从文件路径或文件名中提取后缀def get_ext(fname): dot = fname.rfind(".") # 找最右侧的点 if dot == -1: return "" return fname[dot + 1:]print(get_ext("report.pdf")) # pdfprint(get_ext("archive.tar.gz")) # gzprint(get_ext("README")) # ''易错点:多个点时要用 rfind;dot + 1 才是不含点的扩展名。
4.3 字符串清洗模板#
# 输入:原始字符串 raw# 输出:清洗后的字符串 clean# 用途:去除首尾空白、标准化大小写、替换无效字符raw = " \n\tPython Data Analysis\t\n "clean = raw.strip() # 去除首尾空白clean = clean.lower() # 转小写clean = clean.replace("data", "text")print(clean)易错点:strip() 只去首尾,不处理中间;replace() 返回新字符串,不修改原字符串。
4.4 正则:查找所有匹配#
# 输入:字符串 line# 输出:所有满足规则的子串列表# 用途:提取词、日期、股票代码等import reline = "JAVA PHP Python C++ Perl SQL"pattern = r"\w+"result = re.findall(pattern, line)print(result)# ['JAVA', 'PHP', 'Python', 'C', 'Perl', 'SQL']易错点:\w+ 匹配字母、数字、下划线,不匹配 +,所以 C++ 只得到 C;建议使用原始字符串 r”\w+“。
4.5 正则:替换多个空白为逗号#
# 输入:含多个空格、Tab 的字符串# 输出:用逗号连接的标准化字符串# 用途:清洗不规则分隔符文本import reline = "JAVA PHP Python C++ Perl SQL"pattern = r"\s+" # 一个或多个空白字符new = ","result = re.sub(pattern, new, line)print(result)# JAVA,PHP,Python,C++,Perl,SQL易错点:\s 包含空格、Tab、换行等;re.sub(pattern, new, line) 参数顺序不能错。
4.6 正则:切分字符串#
# 输入:不规则空白分隔的字符串# 输出:词列表# 用途:按复杂分隔符切分文本import reline = "Java PHP Python C++ Perl SQL"pattern = r"\s+"result = re.split(pattern, line)print(result)# ['Java', 'PHP', 'Python', 'C++', 'Perl', 'SQL']易错点:普通 split(” ”) 不适合多个连续空格或 Tab;正则 \s+ 更稳。
4.7 正则:忽略大小写匹配#
# 输入:大小写混合文本# 输出:所有 python 的不同大小写形式# 用途:处理英文文本大小写不一致问题import reline = "Java Python PHP python PYTHON"pattern = r"python"result = re.findall(pattern, line, re.I)print(result)# ['Python', 'python', 'PYTHON']易错点:不加 re.I 时,大小写敏感;re.I 等价于 re.IGNORECASE。
4.8 正则:提取匹配内容和位置#
# 输入:含日期的字符串# 输出:第一个日期及其位置;所有日期及其位置# 用途:信息抽取、文本定位import reline = "order date: 31-08-2019 delivery date: 15-09-2019"pattern = r"\d{1,2}-\d{1,2}-\d{4}"m = re.search(pattern, line)if m: print(m.group()) # 31-08-2019 print(m.span()) # 起止位置 print(m.start(), m.end())for m in re.finditer(pattern, line): print(m.group(), m.span())易错点:re.search 找不到返回 None,必须先判断;findall 只返回内容,要位置用 finditer。
4.9 正则:分组重排日期格式#
# 输入:日期时间字符串,例如 "15/09/2018 18:17"# 输出:标准日期时间格式,例如 "2018-09-15 18:17"# 用途:日期格式清洗import reline = "15/09/2018 18:17"pattern = r"(\d{2})/(\d{2})/(\d{4}).*(\d{2}):(\d{2})"new = r"\3-\2-\1 \4:\5"result = re.sub(pattern, new, line)print(result)# 2018-09-15 18:17易错点:分组编号按左括号出现顺序;替换字符串也建议写成原始字符串 r”\3-\2-\1”。
4.10 编译正则模板#
# 输入:需要多次使用的正则规则# 输出:编译后的 pattern 对象# 用途:同一规则反复匹配,提高效率与可读性import repattern = re.compile(r"python", re.I)line1 = "Python SQL"line2 = "PYTHON Java"print(pattern.findall(line1))print(pattern.findall(line2))适用场景:同一个正则表达式要重复使用很多次;批量处理大量文本。
4.11 jieba 中文分词模板#
# 输入:中文文本 text# 输出:分词列表# 用途:中文文本分析、词频统计、词云绘制import jiebatext = "我来到北京大学信息管理系"# 精确模式:最常用于文本分析words = jieba.cut(text, cut_all=False)words = list(words)print(words)# 搜索引擎模式:适合构建搜索索引search_words = jieba.cut_for_search(text)print(list(search_words))易错点:jieba.cut 返回的是可迭代对象,不是普通列表;如需多次使用,先 list();分词结果依赖词典,不保证完全正确。
4.12 根据课程内容整理的通用模板:中文词频统计#
# 输入:中文文本 text,停用词集合 stopwords# 输出:词频字典或排序列表# 用途:词云、关键词分析、文本主题初步观察import jiebafrom collections import Countertext = "政府工作报告文本内容……"stopwords = {"的", "了", "和", "是", "在", "与", "对", "等"}words = jieba.cut(text)words = [ w.strip() for w in words if w.strip() and w not in stopwords and len(w.strip()) > 1]freq = Counter(words)print(freq.most_common(20))标注:根据课程内容整理的通用模板。PPT 和课堂主要讲分词、停用词和词云流程,未完整展开词频统计代码。
4.13 根据课程内容整理的通用模板:词云绘制#
# 输入:中文文本 text# 输出:词云图片# 用途:文本可视化分析import jiebafrom wordcloud import WordCloudimport matplotlib.pyplot as plttext = "政府工作报告文本内容……"stopwords = {"的", "了", "和", "是", "在", "与", "对", "等"}words = jieba.cut(text)words = [ w for w in words if w.strip() and w not in stopwords and len(w) > 1]word_text = " ".join(words)wc = WordCloud( font_path="SimHei.ttf", # 中文字体路径,需按本机环境修改 background_color="white", max_words=200, max_font_size=100, width=1000, height=700).generate(word_text)plt.imshow(wc)plt.axis("off")plt.show()易错点:中文词云必须设置支持中文的字体,否则可能显示方框;停用词过少会导致“发展、建设、我们”等高频泛词占据画面;词云适合快速展示,不适合替代严谨统计检验。
4.14 根据课程内容整理的通用模板:pandas 文本列处理#
# 输入:DataFrame 中的文本列 df["text"]# 输出:清洗后的文本列# 用途:批量处理表格中的文本字段import pandas as pddf = pd.DataFrame({ "text": [" Python ", "DATA\tAnalysis", None]})df["text_clean"] = ( df["text"] .fillna("") .str.strip() .str.lower() .str.replace(r"\s+", " ", regex=True))print(df)标注:根据课程内容整理的通用模板。课堂提到 Python 和 pandas 中的文本处理,但 PPT 主要展开纯 Python 字符串与正则,pandas .str 系列方法未充分说明。
5. 图表/方法选择指南#
提取固定位置字符 / 字符串结构稳定
| 遇到的问题 | 提取固定位置字符 |
|---|---|
| 数据特点 | 字符串结构稳定 |
| 推荐方法 | 索引、切片 |
| Python 工具 | 原生字符串 |
| 解释重点 | 注意左闭右开 |
提取文件扩展名 / 文件名可能有多个点
| 遇到的问题 | 提取文件扩展名 |
|---|---|
| 数据特点 | 文件名可能有多个点 |
| 推荐方法 | rfind(’.’) + 切片 |
| Python 工具 | 原生字符串 |
| 解释重点 | 找最右侧的点 |
判断输入是否合法 / 手机号、邮箱、身份证号等有规则
| 遇到的问题 | 判断输入是否合法 |
|---|---|
| 数据特点 | 手机号、邮箱、身份证号等有规则 |
| 推荐方法 | 正则表达式 |
| Python 工具 | re.match, re.search |
| 解释重点 | 规则校验,不是枚举全部合法值 |
提取所有日期/代码 / 文本中有多个相似模式
| 遇到的问题 | 提取所有日期/代码 |
|---|---|
| 数据特点 | 文本中有多个相似模式 |
| 推荐方法 | re.findall |
| Python 工具 | re |
| 解释重点 | 只要内容,不要位置 |
提取内容及位置 / 需要知道匹配在哪里
| 遇到的问题 | 提取内容及位置 |
|---|---|
| 数据特点 | 需要知道匹配在哪里 |
| 推荐方法 | re.finditer |
| Python 工具 | re |
| 解释重点 | group/span/start/end |
批量替换格式 / 空格、Tab、日期格式混乱
| 遇到的问题 | 批量替换格式 |
|---|---|
| 数据特点 | 空格、Tab、日期格式混乱 |
| 推荐方法 | re.sub |
| Python 工具 | re |
| 解释重点 | 清洗和标准化 |
按复杂分隔符拆分 / 多空格、Tab、换行混杂
| 遇到的问题 | 按复杂分隔符拆分 |
|---|---|
| 数据特点 | 多空格、Tab、换行混杂 |
| 推荐方法 | re.split(r’\s+‘) |
| Python 工具 | re |
| 解释重点 | 比普通 split 更稳 |
处理中文文本 / 中文无天然空格
| 遇到的问题 | 处理中文文本 |
|---|---|
| 数据特点 | 中文无天然空格 |
| 推荐方法 | 分词 |
| Python 工具 | jieba |
| 解释重点 | 分词错误会影响后续分析 |
画中文词云 / 想快速看主题词
| 遇到的问题 | 画中文词云 |
|---|---|
| 数据特点 | 想快速看主题词 |
| 推荐方法 | 分词 + 去停用词 + 词云 |
| Python 工具 | jieba, wordcloud |
| 解释重点 | 必须设置中文字体 |
做文本分类/聚类 / 文本需进入模型
| 遇到的问题 | 做文本分类/聚类 |
|---|---|
| 数据特点 | 文本需进入模型 |
| 推荐方法 | 向量化表示 |
| Python 工具 | sklearn |
| 解释重点 | 材料中未展开代码,属于后续机器学习连接 |
分析文本语义相似度 / 词、句、文档需比较
| 遇到的问题 | 分析文本语义相似度 |
|---|---|
| 数据特点 | 词、句、文档需比较 |
| 推荐方法 | 词嵌入/句向量 |
| Python 工具 | Word2Vec/BERT 类模型 |
| 解释重点 | 核心是把文本变成向量 |
构建知识图谱 / 想从文本中抽实体和关系
| 遇到的问题 | 构建知识图谱 |
|---|---|
| 数据特点 | 想从文本中抽实体和关系 |
| 推荐方法 | NER + 实体消歧 + 关系抽取 |
| Python 工具 | NLP 工具链 |
| 解释重点 | 从非结构化到结构化 |
自动摘要 / 长文压缩
| 遇到的问题 | 自动摘要 |
|---|---|
| 数据特点 | 长文压缩 |
| 推荐方法 | 抽取式/生成式摘要 |
| Python 工具 | NLP 模型 |
| 解释重点 | 抽取式是排序问题,生成式要求理解与改写 |
舆情/评论分析 / 文本带情绪态度
| 遇到的问题 | 舆情/评论分析 |
|---|---|
| 数据特点 | 文本带情绪态度 |
| 推荐方法 | 情感分析 |
| Python 工具 | NLP/机器学习 |
| 解释重点 | 需注意讽刺、上下文、领域词 |
6. 公式与指标总结#
6.1 字符串索引规则#
对于长度为 n 的字符串 s:
- 正向索引:0, 1, …, n-1
- 反向索引:-n, …, -2, -1
- 对应关系:s[i] == s[i - n],当 0 <= i < n 符号含义:n 是字符串长度;i 是正向索引位置。
适用条件:字符串、列表、元组等序列。
考试易错点:s[-1] 是最后一个字符;s[n] 越界;切片 s[a] 不含 b。
6.2 切片规则#
原文件提示: s[start:end
]
- start:起始位置,包含。
- end:结束位置,不包含。
- step:步长。 直观解释:从 start 开始,按 step 取,到 end 前停止。
计算步骤:确定序列长度;将负索引换成对应正索引;按左闭右开原则截取;根据步长取元素。
考试易错点:s[::-1] 表示反转;s[<3>3>] 取前三个;s[3:] 从第 3 位取到末尾。
6.3 正则数量词#
- / 前一个字符或分组出现 0 次或多次
| 符号 | * |
|---|---|
| 含义 | 前一个字符或分组出现 0 次或多次 |
| 例子 | abc* |
| 可匹配 | ab, abc, abccc |
- / 前一个字符或分组出现 1 次或多次
| 符号 | + |
|---|---|
| 含义 | 前一个字符或分组出现 1 次或多次 |
| 例子 | abc+ |
| 可匹配 | abc, abccc |
? / 前一个字符或分组出现 0 次或 1 次
| 符号 | ? |
|---|---|
| 含义 | 前一个字符或分组出现 0 次或 1 次 |
| 例子 | abc? |
| 可匹配 | ab, abc |
{m} / 前一个字符或分组出现 m 次
| 符号 | {m} |
|---|---|
| 含义 | 前一个字符或分组出现 m 次 |
| 例子 | ab{2}c |
| 可匹配 | abbc |
{m,n} / 前一个字符或分组出现 m 到 n 次
| 符号 | {m,n} |
|---|---|
| 含义 | 前一个字符或分组出现 m 到 n 次 |
| 例子 | ab{1,2}c |
| 可匹配 | abc, abbc |
考试易错点:* 可以匹配 0 次;+ 至少匹配 1 次;{m,n} 中逗号两边含义不同,省略上界表示无穷。
6.4 正则边界匹配#
^ / 字符串开头
| 符号 | ^ |
|---|---|
| 含义 | 字符串开头 |
| 例子 | ^abc |
| 说明 | 匹配以 abc 开头 |
$ / 字符串结尾
| 符号 | $ |
|---|---|
| 含义 | 字符串结尾 |
| 例子 | abc$ |
| 说明 | 匹配以 abc 结尾 |
\A / 整个字符串开头
| 符号 | \A |
|---|---|
| 含义 | 整个字符串开头 |
| 例子 | \Aabc |
| 说明 | 不受多行模式影响 |
\Z / 整个字符串结尾
| 符号 | \Z |
|---|---|
| 含义 | 整个字符串结尾 |
| 例子 | abc\Z |
| 说明 | 不受多行模式影响 |
\b / 单词边界
| 符号 | \b |
|---|---|
| 含义 | 单词边界 |
| 例子 | \babc\b |
| 说明 | 匹配独立单词 |
\B / 非单词边界
| 符号 | \B |
|---|---|
| 含义 | 非单词边界 |
| 例子 | \Babc |
| 说明 | 匹配不在边界处的 abc |
考试易错点:^ 和 match 都与开头有关,但不是同一个概念;普通点号 . 要匹配字面点,应写 .。
6.5 FMM/BMM 最大匹配算法思想#
| 项目 | FMM 正向最大匹配 | BMM 逆向最大匹配 |
|---|---|---|
| 方向 | 左到右 | 右到左 |
| 每步操作 | 取当前起点后最长候选词 | 取当前终点前最长候选词 |
| 匹配失败 | 缩短右端 | 缩短左端 |
| 成功后 | 输出该词,移动到剩余部分 | 输出该词,移动到剩余部分 |
| 典型问题 | 前部局部最优错误 | 后部局部最优错误 |
| 课堂结论 | 可能切错“研究生命的起源” | 大多时候更准,但不绝对 |
考试易错点:最大匹配法依赖词典;“长词优先”不等于语义正确;BMM 不是万能。
6.6 余弦相似度:补充理解#
课堂中老师提到,将词或文本变成向量后,可以计算欧氏距离、余弦距离等。PPT 未展开公式,以下为补充理解。
公式:
符号含义:A, B 为两个词、句子或文档的向量;A · B 为点积;||A||, ||B|| 为向量长度。
直观解释:两个向量方向越接近,余弦值越大,语义可能越相似。
适用条件:文本已被向量化,如词嵌入、句向量、文档向量。
考试易错点:余弦相似度关注方向,不主要关注长度;文本必须先转成向量,不能直接对原始字符串算余弦。
7. 课堂重点与考试提示#
7.1 必背概念#
字符串 / 字符串是由字符组成的有序、不可变序列,支持索引、切片、遍历、成员判断等序列操作。
| 概念 | 字符串 |
|---|---|
| 标准答题表述 | 字符串是由字符组成的有序、不可变序列,支持索引、切片、遍历、成员判断等序列操作。 |
正则表达式 / 正则表达式是用单个模式字符串描述、匹配一类满足特定句法规则的字符串的方法,基本功能包括查找、分组和替换。
| 概念 | 正则表达式 |
|---|---|
| 标准答题表述 | 正则表达式是用单个模式字符串描述、匹配一类满足特定句法规则的字符串的方法,基本功能包括查找、分组和替换。 |
NLP / 自然语言处理是研究如何让计算机处理、理解和生成自然语言的领域,是人工智能的重要方向之一。
| 概念 | NLP |
|---|---|
| 标准答题表述 | 自然语言处理是研究如何让计算机处理、理解和生成自然语言的领域,是人工智能的重要方向之一。 |
中文分词 / 中文分词是将连续的中文字符序列切分成词序列的过程,是中文文本分析的重要预处理步骤。
| 概念 | 中文分词 |
|---|---|
| 标准答题表述 | 中文分词是将连续的中文字符序列切分成词序列的过程,是中文文本分析的重要预处理步骤。 |
未登录词 / 未登录词是词典中未收录但实际文本中出现的词,如新词、品牌名、人名、地名、缩略语等。
| 概念 | 未登录词 |
|---|---|
| 标准答题表述 | 未登录词是词典中未收录但实际文本中出现的词,如新词、品牌名、人名、地名、缩略语等。 |
共指分析 / 共指分析是判断文本中不同表达是否指向同一实体的任务,例如判断“他”指代前文哪一个人。
| 概念 | 共指分析 |
|---|---|
| 标准答题表述 | 共指分析是判断文本中不同表达是否指向同一实体的任务,例如判断“他”指代前文哪一个人。 |
信息抽取 / 信息抽取是从非结构化文本中抽取实体、关系、事件、时间、地点等结构化信息的过程。
| 概念 | 信息抽取 |
|---|---|
| 标准答题表述 | 信息抽取是从非结构化文本中抽取实体、关系、事件、时间、地点等结构化信息的过程。 |
词嵌入 / 词嵌入是将词表示为向量,使词语能够进行计算、比较和建模的方法。
| 概念 | 词嵌入 |
|---|---|
| 标准答题表述 | 词嵌入是将词表示为向量,使词语能够进行计算、比较和建模的方法。 |
文本可视化 / 文本可视化是将复杂文本内容、结构或规律转化为视觉形式,帮助人快速理解文本信息的方法。
| 概念 | 文本可视化 |
|---|---|
| 标准答题表述 | 文本可视化是将复杂文本内容、结构或规律转化为视觉形式,帮助人快速理解文本信息的方法。 |
7.2 必会代码#
| 类型 | 必会代码 |
|---|---|
| 字符串索引 | s[0], s[-1], s[::-1] |
| 文件扩展名 | dot = fname.rfind(”.”); fname[dot+1:] |
| 字符串连接 | ”-“.join(seq) |
| 字符串清洗 | s.strip().lower().replace(old, new) |
| 正则查找全部 | re.findall(pattern, line) |
| 正则查找首个 | m = re.search(pattern, line); m.group(); m.span() |
| 正则替换 | re.sub(r”\s+”, ”,”, line) |
| 正则切分 | re.split(r”\s+”, line) |
| 正则忽略大小写 | re.findall(pattern, line, re.I) |
| 正则分组重排 | re.sub(pattern, r”\3-\2-\1”, line) |
| jieba 分词 | list(jieba.cut(text)) |
| 词云 | WordCloud(font_path=…, max_words=…).generate(text) |
7.3 必会分析思路#
字符串代码题 / 先确定字符串长度与索引,再按左闭右开规则判断输出。
| 题型 | 字符串代码题 |
|---|---|
| 答题步骤 | 先确定字符串长度与索引,再按左闭右开规则判断输出。 |
字符串清洗题 / 先判断脏数据类型:空白、标点、大小写、分隔符、缺失值,再选方法。
| 题型 | 字符串清洗题 |
|---|---|
| 答题步骤 | 先判断脏数据类型:空白、标点、大小写、分隔符、缺失值,再选方法。 |
正则抽取题 / 明确目标模式 → 写 pattern → 选择 findall/search/finditer → 判断返回值。
| 题型 | 正则抽取题 |
|---|---|
| 答题步骤 | 明确目标模式 → 写 pattern → 选择 findall/search/finditer → 判断返回值。 |
正则替换题 / 明确旧模式和新格式 → 必要时用分组 → 用 re.sub。
| 题型 | 正则替换题 |
|---|---|
| 答题步骤 | 明确旧模式和新格式 → 必要时用分组 → 用 re.sub。 |
中文文本分析题 / 读取文本 → 清洗 → 分词 → 去停用词 → 统计/建模/可视化。
| 题型 | 中文文本分析题 |
|---|---|
| 答题步骤 | 读取文本 → 清洗 → 分词 → 去停用词 → 统计/建模/可视化。 |
分词算法题 / 写出词典和最大词长 → 按 FMM/BMM 方向逐步匹配 → 输出结果并评价。
| 题型 | 分词算法题 |
|---|---|
| 答题步骤 | 写出词典和最大词长 → 按 FMM/BMM 方向逐步匹配 → 输出结果并评价。 |
NLP 概念题 / 先定义任务,再说明为什么难,最后举一个歧义或知识缺失例子。
| 题型 | NLP 概念题 |
|---|---|
| 答题步骤 | 先定义任务,再说明为什么难,最后举一个歧义或知识缺失例子。 |
词云分析题 / 说明词云生成步骤,并指出词云只能展示词频/权重,不能直接说明因果或显著性。
| 题型 | 词云分析题 |
|---|---|
| 答题步骤 | 说明词云生成步骤,并指出词云只能展示词频/权重,不能直接说明因果或显著性。 |
7.4 高频易错点#
- 字符串方法通常返回新字符串,不原地修改。
- 切片左闭右开。
find找不到返回 -1,index找不到报错。strip(ch)的参数是字符集合,不是完整子串。- 正则中
.是任意字符,字面点要写\.。 findall不返回位置,位置要用finditer。search找第一个匹配,findall/finditer找所有匹配。- 不加
re.I时大小写敏感。 - 中文分词结果依赖词典,不要盲信工具输出。
- 词云不等于严谨文本分析,只是可视化入口。
7.5 可能出题方式#
| 出题方式 | 示例 |
|---|---|
| 概念题 | 解释正则表达式及其三大功能。 |
| 判断题 | re.search 会返回所有匹配。 |
| 代码阅读题 | 给出字符串和切片表达式,判断输出。 |
| 代码补全题 | 补全用 rfind 提取扩展名的函数。 |
| 正则题 | 写正则匹配日期、股票代码、空白分隔。 |
| 分词题 | 给定词典,用 FMM/BMM 分词。 |
| 应用题 | 给一段中文文本,说明如何绘制词云。 |
| 分析题 | 为什么 NLP 难?结合词义歧义、未登录词、共指分析说明。 |
7.6 转录中与期末有关的明确提示#
课堂转录后半段说明:期末分为开卷代码题和闭卷笔试两个阶段。开卷部分可带资料和电脑,但不能与人交流;闭卷部分不能翻阅资料。老师还强调提前安装常用工具包,如 networkx, sklearn, pandas, jieba, wordcloud 等,避免考试现场安装失败。此部分为课程安排信息,具体以教学网最终通知为准。
8. 期末复习版精简笔记#
8.1 字符串#
- 字符串是有序、不可变序列。
- 可用索引、切片、拼接、重复、成员判断、长度计算等操作。
- 文件扩展名提取:
dot = fname.rfind(".")ext = "" if dot == -1 else fname[dot+1:]8.2 字符串方法#
- 测试:isalpha, isdigit, isalnum, startswith, endswith
- 查找:find 找不到返回 -1;index 找不到报错;rfind 从右找。
- 替换:replace(old, new)
- 拆分:split, partition, rpartition
- 大小写:lower, upper, title
- 剥除:strip, lstrip, rstrip
8.3 正则表达式#
- 定义:用规则匹配一类字符串。
- 三大功能:查找、分组、替换。
- 常用函数:
re.findall(pattern, line)re.search(pattern, line)re.finditer(pattern, line)re.sub(pattern, new, line)re.split(pattern, line)re.match(pattern, line)re.compile(pattern)- 常用模式:\d 数字;\w 字母/数字/下划线;\s 空白;+ 一次或多次;* 零次或多次;{m,n} m 到 n 次;^ 开头;$ 结尾;(…) 分组。
8.4 中文分词#
- 中文没有天然空格,必须分词。
- FMM:从左到右最长匹配。
- BMM:从右到左最长匹配,通常更准但不绝对。
- 分词原则:颗粒度越大越好;非词典词越少越好;单字词越少越好;总词数越少越好。
- jieba:
import jiebawords = list(jieba.cut(text))8.5 NLP 任务#
- 词性标注:标名词、动词等。
- 词义标注:判断词在上下文中的具体含义。
- 未登录词:词典没有的新词、专名、缩略语。
- 共指分析:判断“他/它/该公司”指谁。
- 信息抽取:从文本中抽结构化字段。
- NER:识别人名、地名、机构名等。
- 知识图谱:实体 + 关系。
- 自动文摘:抽取式是排序问题,生成式要求理解与改写。
- 文本表示学习:把词/句/文档变成向量。
- BERT:预训练模型,包含 MLM 和 NSP。
8.6 词云#
流程:
原文件提示: 文本读取 → 清洗 → 分词 → 去停用词 → 统计词频 → 设置字体/形状/最大词数 → 绘制词云
核心代码:
words = jieba.cut(text)word_text = " ".join(words)WordCloud(font_path="SimHei.ttf").generate(word_text)9. 自测题与参考答案
一、选择题#
- 下列哪一个不是 Python 中的序列?
A. 字符串#
B. 列表#
C. 元组#
D. 集合#
答案:D
解析:集合无顺序,不能按位置索引,因此不是序列。字符串、列表、元组都有顺序。
- 对
s = "apple",表达式s[-2]的结果是?
A. p#
B. l#
C. e#
D. 报错#
答案:B
解析:负索引从右向左,s[-1] 是 e,s[-2] 是 l。
find与index的主要区别是?
A. find 从右查找,index 从左查找#
B. find 找不到返回 -1,index 找不到抛异常#
C. find 只能查字符,index 可查字符串#
D. 二者完全相同#
答案:B
解析:这是 PPT 明确强调的差异。
- 下列哪个正则可以匹配 6 位数字?
A. \d{6}#
B. \w{6}#
C. \s{6}#
D. .{6}#
答案:A
解析:\d 表示数字,{6} 表示重复 6 次。
re.findall(pattern, line)的返回值通常是?
A. 第一个匹配对象#
B. 所有匹配结果组成的列表#
C. 是否匹配成功的布尔值#
D. 原字符串#
答案:B
解析:findall 找所有匹配内容,不返回位置。
二、判断题#
- 字符串是可变对象,可以通过
s[0] = 'A'修改第一个字符。
答案:错。
解析:字符串不可变。修改通常通过创建新字符串完成。
s[1:3]包含索引 1 和索引 2,不包含索引 3。
答案:对。
解析:Python 切片是左闭右开。
re.search会返回所有匹配结果。
答案:错。
解析:re.search 只返回第一个匹配对象。所有匹配用 findall 或 finditer。
- 中文分词结果会影响词频统计、词云和后续文本分析。
答案:对。
解析:分词是中文文本分析的前置步骤,错误会向后传递。
- 词云越大的一定是越重要的概念。
答案:错。
解析:词云大小通常反映词频或权重,不一定代表概念重要性,更不能直接代表因果或显著性。
三、简答题#
- 什么是正则表达式?它的基本功能有哪些?
标准答案:正则表达式是用单个模式字符串描述并匹配一类满足特定句法规则的字符串的方法。它的基本功能包括查找、分组和替换。在文本处理、输入校验、网页信息抽取和批量格式转换中常用。
解析:答题时必须包含“规则/模式”“匹配一类字符串”“查找、分组、替换”。
- 为什么中文文本分析通常需要分词?
标准答案:中文文本中词与词之间通常没有空格,而许多文本分析任务需要以词为基本单位进行统计、检索、建模或可视化。因此需要先将连续中文字符序列切分为词序列。分词错误会影响词频统计、信息抽取、文本分类和词云等后续任务。
- 简述 FMM 和 BMM 的区别。
标准答案:FMM 即正向最大匹配,从文本左端开始,每次选取词典中能够匹配的最长词;BMM 即逆向最大匹配,从文本右端开始,每次选取词典中能够匹配的最长词。中文中 BMM 往往比 FMM 更准确,但并不绝对,二者都依赖词典并可能产生歧义。
- 为什么 NLP 难?
标准答案:NLP 难的主要原因是自然语言中存在大量歧义,如词性歧义、词义歧义、分词歧义、共指歧义等。自然语言理解不仅依赖语言规则,还依赖常识、领域知识和上下文。机器缺乏完整知识体系,因此需要通过规则、训练数据、知识库、限定领域等方式降低难度。
四、代码阅读题#
- 阅读代码并写出输出。
s = "apple"print(s[1:4])print(s[::-1])答案:
原文件提示: ppl
elppa
解析:1<4>4> 取索引 1、2、3;[::-1] 反转。
- 阅读代码并写出输出。
import reline = "JAVA PHP Python C++ Perl SQL"print(re.findall(r"\w+", line))答案:
原文件提示: [‘JAVA’, ‘PHP’, ‘Python’, ‘C’, ‘Perl’, ‘SQL’]
解析:\w+ 匹配字母、数字、下划线,不匹配 +,所以 C++ 只提取 C。
- 阅读代码并写出输出。
import reline = "Java Python python PYTHON"print(re.findall(r"python", line, re.I))答案:
原文件提示: [‘Python’, ‘python’, ‘PYTHON’]
解析:re.I 表示忽略大小写。
五、代码补全题#
- 补全函数:返回文件扩展名。
def get_ext(fname): dot = fname.____(".") if dot == -1: return "" else: return fname[____:]答案:
def get_ext(fname): dot = fname.rfind(".") if dot == -1: return "" else: return fname[dot + 1:]解析:用 rfind 找最右侧的点;扩展名从 dot + 1 开始。
- 补全代码:把多个空白替换为逗号。
import reline = "JAVA PHP Python C++ Perl SQL"result = re.____(r"____", ",", line)print(result)答案:
import reline = "JAVA PHP Python C++ Perl SQL"result = re.sub(r"\s+", ",", line)print(result)解析:\s+ 匹配一个或多个空白字符,re.sub 用于替换。
- 补全代码:使用 jieba 精确模式分词。
import jiebatext = "我来到北京大学信息管理系"words = jieba.____(text, cut_all=____)print("/ ".join(words))答案:
import jiebatext = "我来到北京大学信息管理系"words = jieba.cut(text, cut_all=False)print("/ ".join(words))解析:cut_all=False 是精确模式,适合常规文本分析。
六、数据分析应用题#
- 给定一批政府工作报告文本,要求绘制词云。请写出分析步骤。
标准答案:读取文本数据;对文本进行清洗,如去除换行、特殊符号、无意义空白;使用 jieba 进行中文分词;去除停用词,如“的、了、和、是”等;统计词频或将分词结果用空格连接;设置词云参数,包括中文字体、背景色、最大显示词数、词云形状等;使用 WordCloud 生成词云;结合高频词解释文本主题,但注意词云只反映词频或权重,不能直接说明因果关系或统计显著性。
- 给定一段网页文本,要求提取其中所有 6 位股票代码。你会怎么做?
标准答案:可使用正则表达式 \d{6} 匹配 6 位数字,并用 re.findall 提取所有匹配。
import rehtml_text = "股票代码包括 600519、000001、300750 等。"codes = re.findall(r"\d{6}", html_text)print(codes)解析:股票代码具有“6 位数字”这一规则,因此适合用正则表达式抽取。
- 给定句子“研究生命的起源”和词典
{研究, 研究生, 生命, 命, 的, 起源},说明为什么 FMM 可能出错。
标准答案:FMM 从左向右匹配,若最大词长允许,它会优先匹配“研究生”,剩余部分变成“命的起源”,可能进一步切成“命 / 的 / 起源”。结果为“研究生 / 命 / 的 / 起源”,语义明显不符合原句。错误原因是最大匹配只根据词典和局部最长词决策,缺乏全局语义理解。
10. 一页纸考前速览#
A. 必背定义#
- 字符串:由字符组成的有序、不可变序列。
- 正则表达式:用规则字符串匹配一类字符串,核心功能是查找、分组、替换。
- NLP:让计算机处理、理解和生成自然语言的技术领域。
- 中文分词:将连续中文字符切分为词序列,是中文文本分析前处理。
- 未登录词:词典中没有但文本中出现的词,如新词、品牌名、人名、缩略语。
- 词嵌入:把词表示为向量,使文本可计算、可比较。
- 词云:用词的视觉大小展示词频或权重的文本可视化方法。
B. 必会代码#
# 反转字符串s[::-1]# 提取扩展名dot = fname.rfind(".")ext = "" if dot == -1 else fname[dot+1:]# 查找s.find(t) # 找不到 -1s.index(t) # 找不到报错# 清洗s.strip().lower().replace(old, new)# 正则import rere.findall(r"\w+", line)re.search(r"\d{1,2}-\d{1,2}-\d{4}", line)re.finditer(r"\d{6}", line)re.sub(r"\s+", ",", line)re.split(r"\s+", line)# 忽略大小写re.findall(r"python", line, re.I)# 分组重排re.sub(r"(\d{2})/(\d{2})/(\d{4})", r"\3-\2-\1", line)# jiebaimport jiebawords = list(jieba.cut(text))# 词云from wordcloud import WordCloudwc = WordCloud(font_path="SimHei.ttf").generate(" ".join(words))C. 正则速查#
| 模式 | 含义 |
|---|---|
| \d | 数字 |
| \w | 字母、数字、下划线 |
| \s | 空白 |
| . | 除换行外任意字符 |
| * | 0 次或多次 |
| + | 1 次或多次 |
| ? | 0 次或 1 次 |
| {m,n} | m 到 n 次 |
| ^ | 开头 |
| $ | 结尾 |
| (…) | 分组 |
D. 中文文本分析流程#
原文件提示: 读取文本 → 清洗特殊字符、空白、标点 → jieba 分词 → 去停用词 → 词频统计 / 向量化 / 信息抽取 → 词云、分类、检索、摘要等任务
E. 高频易错点#
- 切片左闭右开。
- find 找不到返回 -1,index 找不到报错。
- 字符串方法不原地修改。
- strip(“abc”) 删除首尾所有 a/b/c,不是删除完整 “abc”。
- 正则中 . 不是普通点,普通点写 .。
- findall 没有位置,位置用 finditer。
- search 只找第一个。
- re.I 才能忽略大小写。
- 中文分词依赖词典,结果不一定正确。
- 词云只展示词频/权重,不等于严谨结论。
附录 A 外部补充#
内容来源:外部补充。 本附录不属于课程原文件。它依据经典教材与主流库的官方文档补充现代用法和容易被忽略的分析规范;若与课堂指定版本或教师口径不同,考试时以课程要求为准。
A.1 NumPy 广播与向量化#
NumPy 广播从数组形状的最右侧维度开始比较;两个维度相等,或其中一个为 1,即可兼容。广播通常能用底层数组运算替代 Python 层循环,但也可能产生很大的中间数组,所以“能广播”不等于“总是最省内存”。
import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6]]) # shape: (2, 3)scale = np.array([10, 100, 1000]) # shape: (3,)result = x * scale # shape: (2, 3)复习提示:遇到 operands could not be broadcast together,从右向左写出两个 shape 再逐维比较。参见 NumPy Broadcasting。
A.2 pandas 新旧 API 对照#
原文件使用 DataFrame.applymap 表示逐元素处理。较新的 pandas 文档已将它标为弃用,推荐使用 DataFrame.map;DataFrame.apply 仍表示沿行或列应用函数,Series.map 仍适合对单个 Series 做映射。
# 课程旧写法:逐元素df.applymap(lambda x: x * 2)
# 新版 pandas 推荐写法:逐元素df.map(lambda x: x * 2)
# 沿某个轴处理整列或整行df.apply(func, axis=0) # 逐列df.apply(func, axis=1) # 逐行复习提示:考试代码应遵循教师指定版本;真实项目再按安装版本查官方 API。参见 pandas DataFrame.applymap。
A.3 Matplotlib 的对象式写法#
简单交互绘图使用 plt.* 很方便;多子图、可复用函数或复杂定制更适合显式创建 Figure 和 Axes,再调用 ax.plot、ax.set_title 等方法。官方快速入门也建议在复杂图中优先采用对象式接口。
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(7, 4), layout="constrained")ax.plot(x, y, label="series")ax.set(xlabel="x", ylabel="y", title="Trend")ax.legend()fig.savefig("trend.png", dpi=200)参见 Matplotlib Quick start guide。
A.4 机器学习中的数据泄漏与 Pipeline#
必须先划分训练集和测试集,再只用训练集拟合标准化、缺失值填补、特征选择或 PCA 等预处理步骤。若先在全体数据上 fit_transform,测试集信息会进入训练过程,得到过于乐观的评价。Pipeline 可把预处理与模型绑定,使交叉验证只在每个训练折上拟合预处理器。
from sklearn.model_selection import train_test_split, cross_val_scorefrom sklearn.pipeline import make_pipelinefrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegression
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, stratify=y, random_state=42)
model = make_pipeline( StandardScaler(), LogisticRegression(max_iter=1000))model.fit(X_train, y_train)test_score = model.score(X_test, y_test)cv_scores = cross_val_score(model, X_train, y_train, cv=5)参见 scikit-learn Common pitfalls 与 Cross-validation。
A.5 可复现分析的最小规范#
- 固定随机种子,并记录 Python 与核心库版本。
- 保留原始数据,只对副本或明确的数据处理流水线进行转换。
- 把“读取—清洗—特征—分析—输出”写成可重复执行的步骤。
- 对每次合并、去重、缺失值处理记录行数变化,防止静默丢数。
- 同时报告指标值、样本量、数据划分方式和评价口径;不要只报单个最高分。
- 图表必须有标题、轴标签、单位、图例或必要注释,并说明图中结论的边界。
附录 B 参考资料#
用途说明: 以下仅用于文末外部补充和延伸学习,不改变原文件的课程范围。
- Wes McKinney, Python for Data Analysis 3E Open Edition:覆盖 Python 内置结构、NumPy、pandas、数据读写、清洗、聚合、可视化和建模接口。
- Jake VanderPlas, Python Data Science Handbook:以 Jupyter Notebook 形式系统介绍 NumPy、pandas、Matplotlib 与 scikit-learn。
- NumPy User Guide、pandas Documentation、Matplotlib Documentation、scikit-learn User Guide:用于核对当前 API 与推荐实践。
发布检查清单#
- 网站已启用 GitHub Flavored Markdown 或等价的表格、任务列表支持。
- 代码块启用了 Python 语法高亮。
- 页面容器对宽表格启用了横向滚动,移动端不压缩表格内容。
- 已检查中文字体、反斜线正则表达式和数学符号的显示。
- 已保留“原文件内容”和“外部补充”来源标记。
- 课程考试形式与工具包要求已按教学网最终通知复核。