数据科学基础考试复习:NumPy、Pandas与统计建模知识地图
1. 先把范围摸清楚:这门课到底考什么
每年春天都有人拿着同一份数据科学基础的课程大纲来找我,问的问题也高度雷同:东西太多,不知道从哪儿下手。这篇考试参考就是按“某理工类院校2023年春季学期”那套课程体系整理的复习思路,把一学期的内容压成一张能带进自习室的知识地图。它解决的不是“知识点没有”的问题,而是“知识点散落各处、串不起来、看完就忘”的问题。适合三类人:一是零基础或半基础、课上听懂了但一合书就空的同学;二是时间只剩两三周、需要抓大放小的同学;三是想把课程内容和实际数据分析工作接上的同学。文中的例题、数据、报错信息都是我按常见教学场景重写的,不涉及任何真实试卷。
1.1 从“数据到结论”的四段链路
我习惯把整门课切成四段链路,这个切法比按章节顺序复习有效得多,因为它对应的是考试出题的逻辑。第一段是数据获取与表示,核心问题是“一份数据在程序里长什么样”,落在 NumPy 的 ndarray 和 Pandas 的 DataFrame 上,考的是数据结构认知。第二段是数据清洗与变换,核心问题是“脏数据怎么变成能算的数据”,落在缺失值、异常值、类型转换、分组聚合上,这一段的实操题密度最高。第三段是统计推断,核心问题是“样本能不能代表总体”,落在描述统计、分布、抽样、假设检验、置信区间上,概念题和计算题都从这里出。第四段是建模与评估,核心问题是“模型好不好、凭什么说它好”,落在回归、分类、聚类和评估指标上。
这四段的顺序不是随便排的。前一段的输出是后一段的输入:没有干净的 DataFrame,后面的 groupby 和建模全是幻觉;不懂抽样和分布,假设检验的 p 值就只能死记硬背。所以复习的时候我建议按链路走一遍,而不是按教材目录走。教材目录是按知识点难度排的,链路是按“解决一个问题需要什么”排的,后者更接近考场上你实际要做的思考动作。举个具体例子:一道题给你一份带缺失值的销售表,让你判断不同区域的客单价是否有显著差异。这道题横跨三段——清洗、分组、检验。如果你脑子里是目录结构,你会想“这是第几章”;如果是链路结构,你会直接反应“先 dropna 还是填充,再 groupby 求均值,最后做两样本 t 检验”。差别就在这儿。
提示:复习时每看完一个知识点,强迫自己回答一句“它在链路里的哪一环、它的输入是什么、输出交给谁”。答不上来的,说明这个点你只是记住了名词。
1.2 卷面结构与分值分布的合理推测
这类课程通常采用“闭卷概念 + 开卷或上机实操”的混合考法,我把常见的分值结构整理成下表,注意这是基于同类课程普遍做法的推断,不是你手上那张卷子的承诺,用来分配时间足够。
| 题型 | 常见占比 | 主要考查链路 | 复习性价比 |
|---|---|---|---|
| 选择/判断 | 15%–20% | 全链路概念辨析 | 高,但要防混淆项 |
| 简答/名词解释 | 15%–20% | 第三段统计推断 | 中,靠理解不靠背 |
| 计算题 | 20%–25% | 描述统计、检验、回归 | 高,公式必须手推一遍 |
| 代码阅读/填空 | 15%–20% | 第一、二段 | 高,认得 API 就得分 |
| 综合上机题 | 20%–30% | 二、三、四段串联 | 最高,但需要提前练手速 |
从这张表能看出一个反直觉的结论:概念题的性价比其实没有想象中高。选择题 20 分,你背三天可能从 12 分提到 16 分;而上机题 25 分,你练三个下午可能从 8 分提到 20 分。原因是概念题的混淆项设计得很刁,投入产出比低;上机题的评分点非常明确,跑通就给分。所以我给时间紧张的同学的建议是:先保上机和计算,再补简答,最后才去抠选择题的边角概念。这个顺序和大多数人的直觉是反的,但实测下来分数提升最快。
1.3 复习优先级:三档分类法
把所有知识点粗暴地分成三档,比列一张长长的清单有用。A 档是“必须能默写代码”:DataFrame 的筛选与切片、缺失值处理、groupby 聚合、merge 连接、matplotlib 基本绘图、训练测试集划分、混淆矩阵计算。这些是上机题的骨架,任何一个卡壳,整道题就废了。B 档是“必须能说清原理并手算”:均值中位数众数、方差标准差、正态分布与标准化、t 检验的假设与结论表述、最小二乘的系数含义、R² 的解释、精确率与召回率的换算。这些是计算题和简答题的主力。C 档是“知道是什么、能选对就行”:各类聚类算法的差异、降维的直观意义、过拟合与正则化的定性理解、数据可视化的图表选型。
分档的意义在于止损。很多人复习到考前两天还在纠结“层次聚类和 K-means 到底哪个用在哪”,这属于典型的 C 档问题占了 A 档的时间。我的做法是:A 档内容每天动手敲一遍,不看笔记;B 档内容拿白纸手推公式,推不出来再看;C 档内容只在睡前翻一遍,形成模糊印象即可。这个方法听着粗糙,但它把有限的注意力压在了真正能拿分的地方。
2. 数据处理三件套:NumPy、Pandas、可视化练到什么程度
这一块是整门课的地基,也是上机题最容易翻车的地方。翻车原因往往和技术难度无关,大多是对“索引”和“轴”这两个概念的理解停留在表面。我带人复习时发现一个规律:凡是 NumPy 的 axis 说不清楚的,Pandas 的 groupby 大概率也写不利索,因为两者共享同一套“沿哪个方向压缩”的心智模型。所以这章我按“先建立模型、再记 API”的顺序来写。
2.1 NumPy:轴、广播、向量化三件事
axis 的本质是“被压缩掉的那一维”。这是我最常讲的一句话。a.sum(axis=0)对二维数组来说,是把行方向压掉,剩下的每一列变成一个数,所以结果长度等于列数。你可以用生活化的方式记:axis=0 是“从上往下压扁”,就像把一摞纸从顶上按下去,剩下的是一行标签;axis=1 是“从左往右压扁”,把每一行压成一个数。考试里凡是出现“按行求和”“按列求均值”这种表述,先问自己一句“压掉的是哪一维”,比死记硬背可靠得多。
import numpy as np a = np.array([[1, 2, 3], [4, 5, 6]]) print(a.sum(axis=0)) # [5 7 9] 压掉行,每列一个和 print(a.sum(axis=1)) # [6 15] 压掉列,每行一个和 print(a.mean(axis=0)) # [2.5 3.5 4.5]广播(broadcasting)是另一个高频考点,出题形式通常是给一个形状不匹配的运算,问你结果形状是什么或者为什么报错。规则只有三条,按顺序判断:从最右边的维度开始对齐;维度相等或其中一个为 1 才能运算;缺失的维度补 1。比如形状(3, 4)和(4,)相加,后者被当成(1, 4),然后沿第 0 维复制三份,结果是(3, 4)。而(3, 4)和(3,)相加就会报错,因为右对齐后是 4 和 3,既不等也没有 1。
x = np.ones((3, 4)) y = np.arange(4) # 形状 (4,) print((x + y).shape) # (3, 4),y 被广播成 (3, 4) z = np.arange(3) # 形状 (3,) # print((x + z).shape) # 报错:4 与 3 无法对齐向量化思维是老师最想看到的东西。凡是让你“用循环把数组每个元素加 1”的题,标准答案一定是a + 1。这不仅是因为代码短,更因为向量化把“对每个元素做什么”变成了“对整个数组做什么”,这是数据科学和传统编程在思维方式上的分水岭。考试里如果出现“以下哪种写法效率最高”的选择题,选项里有 for 循环和向量化运算,闭着眼睛选向量化。
注意:
np.array和np.asarray的区别常被拿来出判断题。前者总是复制一份新内存,后者在输入已经是 ndarray 时直接返回原对象。理解了“是否复制”这个点,这类题就不会错。
2.2 Pandas:索引、缺失值、groupby 三大高频考点
Pandas 的考点密度远高于 NumPy,因为它更贴近真实数据处理。我按出现频率排了三个必练项。
第一是索引与切片。loc按标签,iloc按位置,这两个绝对不能混。记忆方法是看字母:loc里的 l 想成 label,iloc里的 i 想成 integer。布尔索引是另一个必考点,形式是df[df['列名'] > 阈值],多条件时每个条件都要加括号、用&或|连接,不能用and/or。这个细节每年都有人写错,原因是 Python 的and是短路的标量运算,作用在 Series 上会直接抛异常。
import pandas as pd df = pd.DataFrame({ 'city': ['A', 'B', 'A', 'C'], 'sales': [100, 200, 150, 80], 'qty': [2, 5, 3, 1] }) # 单条件 print(df[df['sales'] > 100]) # 多条件,括号 + & print(df[(df['sales'] > 100) & (df['qty'] >= 3)]) # loc 与 iloc print(df.loc[0, 'city']) # 标签 print(df.iloc[0, 1]) # 位置第二是缺失值处理。这一块出题喜欢考“判断某个操作之后缺失值的数量变成了多少”,所以你必须清楚每个函数的默认行为。dropna()默认丢弃任何含缺失值的行(how='any'),how='all'才是全空才丢。fillna()的常见写法是填均值、中位数、众数或前向填充method='ffill'。还有一个坑:默认情况下dropna不会修改原表,除非加inplace=True或者重新赋值。考试里问“执行后 df 有多少行”,如果没注意这一点,答案会差很多。
data = pd.DataFrame({ 'x': [1, None, 3, 4], 'y': [None, 2, 3, None] }) print(data.dropna().shape) # (1, 2),只剩第 3 行 print(data.dropna(how='all').shape) # (4, 2),没有全空行 print(data['x'].fillna(data['x'].mean())) # 用均值填 x 列第三是 groupby 聚合,这是上机综合题的核心动作。基本套路是“分组键 → 聚合函数 → 结果重塑”,df.groupby('city')['sales'].mean()是最小可用示例。进阶考点有两个:一是agg传入多个函数,结果会变成多层列索引;二是transform与agg的区别——agg把每组压成一个值,transform保持原表行数不变,把组内统计值广播回每一行。这个区别在实际工作里极其常用,比如“算每个城市销售额占本城市总额的比例”,就得用transform。
# agg:每组一个值 print(df.groupby('city')['sales'].agg(['sum', 'mean', 'count'])) # transform:保持行数,广播组内统计值 df['city_total'] = df.groupby('city')['sales'].transform('sum') df['ratio'] = df['sales'] / df['city_total'] print(df)心得:
groupby之后的reset_index()别忘了。结果表如果带着多层索引去做后续 merge,十有八九对不上,报错信息还特别隐晦。
2.3 可视化:图表选型与三个常见陷阱
可视化的考题分两类:一类是“读图说话”,给一张图让你描述趋势或异常;一类是“写代码画图”。前者的得分点在于用词准确——说“上升趋势”要带上“整体”,说“异常点”要指出大致位置,别只写“有波动”,那等于没答。后者要记牢的 API 不多:plt.plot折线、plt.bar柱状、plt.scatter散点、plt.hist直方、plt.boxplot箱线,再加plt.xlabel/ylabel/title/legend这几个装饰函数,足够应付绝大多数上机题。
图表选型有个简单口诀:看分布用直方图或箱线图,看关系用散点图,看对比用柱状图,看趋势用折线图。这条口诀覆盖了 90% 的场景题。
三个常见陷阱值得单独说。第一,直方图和柱状图不是一回事:直方图描述连续变量的分布,横轴是分箱区间,柱子之间没有间隙;柱状图比较类别,柱子之间有间隙。考选择题时把这两个混起来的选项大概率是错的。第二,中文显示乱码,这是上机现场最打击人的问题,代码逻辑全对,图出来一堆方块。原因通常是字体未设置,解决思路是显式指定一个系统里存在的中文字体,而不是指望默认配置。第三,plt.show()的位置,在一张图里多次调用plot会叠加在同一坐标系,想分开画要先plt.figure()新建画布,否则两条毫不相干的曲线会画到一起,看起来像个重大发现。
3. 统计与概率:不背公式的推法
统计部分是很多人复习的痛点,痛点不在难,而在“公式长得像天书”。我的经验是,这部分真正需要背的公式其实只有四五个,其余都能推出来或者靠语义理解。下面按“能推就不背”的原则展开。
3.1 描述统计与分布形态:三个数看穿一份数据
拿到任何一组数据,先看三个东西:集中趋势、离散程度、分布形状。集中趋势就是均值、中位数、众数,考试常考的是它们三者的关系——在右偏分布(长尾在右)里,均值 > 中位数 > 众数;左偏则反过来。这个关系不用记,画个草图就出来了:长尾把均值往尾巴方向拽,中位数只关心中间位置,不受极端值影响。
离散程度常考方差和标准差,重点在于样本方差分母是 n-1 而不是 n。为什么要减 1?因为样本均值本身是从样本里估出来的,用它算偏差会系统性地低估离散程度,除以 n-1(自由度)是一种无偏修正。这个概念题出得非常多,标准答法是“样本方差使用 n-1 是为了得到总体方差的无偏估计”。标准差就是方差开根号,好处是量纲和原数据一致,所以解释“波动大小”时用标准差更直观。
分布形状看偏度和峰度,多数课程只要求定性理解:偏度衡量不对称程度,0 为对称,正为右偏;峰度衡量尾部厚度,正态分布的峰度基准是 3(超额峰度为 0)。标准化是必考操作,公式z = (x - μ) / σ,含义是“这个值离均值有几个标准差”。标准化之后均值变 0、标准差变 1,这个性质在后面的建模和异常值判断里都会用到。
注意:判断异常值时用 3σ 原则还是 IQR 原则,要看题目给的条件。3σ 假设近似正态,IQR 更稳健。如果题目数据里明显有极端值,用 IQR 更合适,答的时候最好说明理由,这种“说明理由”往往是简答题的加分点。
3.2 假设检验:p 值到底怎么解释
假设检验是简答题的重灾区,因为很多人背了流程却说不清含义。我把核心浓缩成一句话:p 值是在“原假设为真”的前提下,观察到当前数据或更极端情况的概率。注意它不是“原假设为真的概率”,这个混淆是最经典的错误选项。p 值小,说明“如果原假设成立,出现这种数据太巧了”,于是我们倾向于拒绝原假设;p 值不小,只能说“没有足够证据拒绝”,不能说“原假设正确”。这个措辞差异在简答题里是硬性得分点。
检验流程可以固定成五步,考试时按步写,条理分就稳了:提出原假设与备择假设 → 选择检验方法 → 设定显著性水平 α(常取 0.05)→ 计算统计量与 p 值 → 做出结论并解释。方法选择看三件事:比较什么(均值、比例、方差)、几组(单样本、两样本、多样本)、样本是否独立、方差是否已知。两独立样本均值比较用 t 检验,配对数据用配对 t 检验,三组以上用方差分析,类别变量的关联用卡方检验。
from scipy import stats group_a = [23, 25, 28, 30, 22, 27] group_b = [31, 33, 29, 35, 30, 34] t_stat, p_value = stats.ttest_ind(group_a, group_b) print(f"t = {t_stat:.3f}, p = {p_value:.4f}") alpha = 0.05 if p_value < alpha: print("拒绝原假设,两组均值存在显著差异") else: print("不能拒绝原假设,尚无足够证据表明存在差异")第一类错误和第二类错误也是必考项。第一类错误是“原假设为真却拒绝了”,也叫“弃真”,概率就是 α;第二类错误是“原假设为假却没拒绝”,也叫“存伪”,概率记作 β。降低 α 会减少第一类错误,但同时会增大第二类错误,两者此消彼长。理解了这个权衡,就能回答“为什么不能把 α 设得特别小”——因为会变得过于保守,真有问题也检不出来。
3.3 相关、回归与模型诊断
相关和回归是两件事,但考试常放在一起考。相关系数 r 衡量线性相关强度和方向,取值 -1 到 1,绝对值越大越强,符号表示方向。关键点在于:r 只反映线性关系,r 接近 0 不代表没关系,可能存在很强的非线性关系。这句话在判断题里出现的频率极高。另外 r 对异常值敏感,一个极端点就能把 r 从 0.8 拉到 0.2,所以看到相关系数时先想一下数据里有没有离群点。
一元线性回归的模型是y = β₀ + β₁x + ε,最小二乘的目标是让残差平方和最小。β₁ 的估计公式是Σ(x-x̄)(y-ȳ) / Σ(x-x̄)²,这个公式建议手推一遍,因为计算题经常给一张小表让你算。R² 的含义是“模型解释了多少比例的因变量变异”,取值 0 到 1,越接近 1 拟合越好,但要注意 R² 高不代表模型合理——加变量一定会让 R² 不降,所以多元回归里要看调整后的 R²。
模型诊断这块,常考三个残差假设:线性、独立、等方差、正态(常说的四项)。残差图如果呈现喇叭形,说明方差不齐;如果呈现弯曲的 U 形,说明线性假设不成立,可能需要加二次项或做变换。这些判断在简答题里属于“看图说诊断”,答法是先描述图形特征,再对应到哪条假设被违反,最后给出改进方向。三步走完,分数基本拿满。
4. 机器学习入门:模型、划分与评估
这部分内容在课程里通常只要求“会用、会解释”,不要求推导。但恰恰因为不要求推导,很多同学就只记了名字,一到评估指标换算就露馅。我的建议是把重心放在“数据怎么分、指标怎么算、结果怎么解释”这三件事上,算法内部的数学可以放一放。
4.1 训练集测试集划分与交叉验证
划分的逻辑很简单:模型在训练集上学,在没见过的测试集上考,才能反映泛化能力。常见比例是 7:3 或 8:2,数据量小时用 6:4。划分时必须注意两点。第一是随机性,要设随机种子,否则每次跑出来结果都不同,实验无法复现。第二是分层,分类问题里如果正负样本不均衡,普通随机划分可能让某一类在测试集里几乎不出现,这时候要用分层抽样,保证训练集和测试集的类别比例与原数据一致。
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42, stratify=y # 分层抽样,保持类别比例 )交叉验证解决的是“一次划分不巧”的问题。K 折交叉验证把数据切成 K 份,每次拿一份当验证集、其余当训练集,跑 K 次取平均。K 常取 5 或 10。它的好处是每个样本都当过一次验证集,评估结果更稳定;代价是计算量变成 K 倍。简答题常考“交叉验证的作用”,标准答法是“更充分地利用数据、降低评估结果对单次划分的敏感性、更稳定地估计模型泛化性能”。还有一个高频陷阱叫数据泄漏,典型例子是在划分之前就对全量数据做了标准化或填充缺失值,导致测试集的信息提前进入了训练过程。正确顺序永远是先划分、再在训练集上拟合预处理器、最后用同一个预处理器变换测试集。
4.2 常见算法的核心假设对比
课程里涉及的算法不会太多,我把常见的几类整理成对照表,记忆重点放在“它靠什么做判断”上,而不是公式。
| 算法 | 核心思路 | 关键假设/参数 | 典型适用场景 |
|---|---|---|---|
| 线性回归 | 找一条直线使残差平方和最小 | 线性关系、残差独立同分布 | 连续值预测 |
| 逻辑回归 | 线性组合后过 sigmoid 得到概率 | 特征与对数几率线性相关 | 二分类、需要概率输出 |
| KNN | 看最近的 K 个邻居投票 | 距离度量有意义、特征需标准化 | 小样本、低维 |
| 决策树 | 按特征阈值不断切分,降低不纯度 | 容易过拟合,需限制深度 | 可解释性要求高 |
| 随机森林 | 多棵树投票,降低方差 | 树之间相关性越低越好 | 表格数据通用 |
| K-means | 迭代更新簇中心,最小化簇内距离 | 需事先指定 K、对初始中心敏感 | 无标签分群 |
这张表里最值得花时间的是特征标准化那一条。KNN 和 K-means 都是基于距离的,如果一个特征量纲是千级、另一个是小数级,距离会被大数值特征完全主导,结果等于只用了一个特征。这个点在简答题里反复出现,答的时候要说清“为什么”而不只是“要标准化”。
决策树那一条的考点是过拟合。树越深,训练集上越准,但测试集上可能崩。控制手段是限制最大深度、限制叶子节点最小样本数、剪枝。这个逻辑和正则化的思路是一致的:给模型加约束,让它在训练集上“别学得太死”。理解了这个统一视角,很多零散的概念就能串起来。
4.3 评估指标:从混淆矩阵推出来
分类问题的评估指标,我从来不建议背公式,因为全部能从混淆矩阵推出来。混淆矩阵四个格子:真正例 TP、假正例 FP、真负例 TN、假负例 FN。准确率是(TP+TN)/总数,精确率是TP/(TP+FP),回答的是“我说是正例的里面,有多少真是正例”;召回率是TP/(TP+FN),回答的是“真正的正例里,我抓到了多少”。这两个指标的分母不同,一个是预测为正的,一个是实际为正的,记住这个区别就不会混。
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score y_true = [1, 0, 1, 1, 0, 0, 1, 0] y_pred = [1, 0, 0, 1, 0, 1, 1, 0] print(confusion_matrix(y_true, y_pred)) print("精确率:", precision_score(y_true, y_pred)) print("召回率:", recall_score(y_true, y_pred)) print("F1:", f1_score(y_true, y_pred))精确率和召回率经常打架,此消彼长,所以有了 F1,它是两者的调和平均:2PR/(P+R)。为什么用调和平均而不是算术平均?因为调和平均对较小的值更敏感,只要有一个指标很低,F1 就会被拉下来,这样更能反映“两个都得兼顾”。
什么时候看重精确率、什么时候看重召回率,这是简答题的常客。判断标准是哪种错误代价更大。垃圾邮件识别,把正常邮件误判为垃圾(FP)代价大,所以看重精确率;疾病筛查,漏诊(FN)代价大,所以看重召回率。答题时把“代价”这两个字写出来,基本就是标准答案的骨架。
ROC 曲线和 AUC 也常考。ROC 的横轴是假正例率FP/(FP+TN),纵轴是真正例率TP/(TP+FN),曲线越靠左上越好,AUC 是曲线下面积,取值 0.5(随机猜)到 1(完美)。AUC 的好处是不依赖具体阈值,衡量的是模型整体的排序能力。这个“不依赖阈值”是它的核心卖点,也是简答题的得分点。
5. 上机题与编程题的答题套路
上机题是拉开差距的地方,也是最容易因为非技术原因丢分的地方。我见过太多人思路完全正确,最后因为变量名拼错、缩进错位、忘记导入库而拿不到分。这一章讲的是“怎么把会的东西稳稳地变成分”。
5.1 代码题的评分逻辑
评分通常是按点给分,不是看整体跑不跑通。一道 15 分的综合题可能拆成:正确读入数据 2 分、正确清洗 3 分、正确分组聚合 4 分、正确建模 3 分、正确输出结果 3 分。这意味着即使最后一步崩了,前面的分照样能拿。所以策略是:先把结构搭出来,每一步都 print 一下中间结果,让它至少能跑到某一步,而不是追求一次写对。
具体做法是写“防御性代码”:读入后立刻打印df.shape和df.head(),清洗后打印缺失值数量,分组后打印结果行数。这些打印语句不占几分,但它们能在你卡住时告诉你错在哪一步。很多人不愿意写,觉得浪费时间,实际上这是最省时间的调试手段。
import pandas as pd # 第一步:读入并检查 df = pd.read_csv('data.csv') print('形状:', df.shape) print(df.head()) # 第二步:清洗 print('缺失值:', df.isnull().sum().to_dict()) df = df.dropna(subset=['amount']) df['amount'] = df['amount'].astype(float) # 第三步:分组 result = df.groupby('region')['amount'].agg(['sum', 'mean', 'count']) print(result) # 第四步:输出 result.to_csv('result.csv', encoding='utf-8')5.2 常见报错与排查
上机现场最常遇到的报错就那几种,提前认识一遍,考场上能省十分钟。
| 报错信息关键词 | 常见原因 | 处理思路 |
|---|---|---|
| KeyError | 列名拼错、含空格、大小写不一致 | 打印df.columns对照 |
| ValueError: could not convert | 列里混了非数字字符 | 先看唯一值,再to_numeric(errors='coerce') |
| SettingWithCopyWarning | 链式索引赋值 | 改用.loc[行, 列] = 值 |
| IndexError | iloc 越界 | 打印df.shape核对范围 |
| 中文乱码 | 字体未设置 | 显式指定中文字体 |
| 图形不显示 | 缺plt.show() | 补上,或检查后端 |
SettingWithCopyWarning值得单独说一句,因为它是唯一一个“不报错但结果可能不对”的警告。根源是df[df['a'] > 1]['b'] = 0这种链式写法作用在了一个临时副本上,原表没变。正确写法是df.loc[df['a'] > 1, 'b'] = 0,用一次 loc 完成筛选和赋值。
提示:考场如果时间紧,先让代码跑通再优化写法。
SettingWithCopyWarning是警告不是错误,不影响出结果,别在这上面死磕。
5.3 时间分配与检查清单
我给的时间分配是:读题 5 分钟、搭骨架 10 分钟、填充逻辑 30 分钟、调试 10 分钟、检查 5 分钟。读题那 5 分钟不要省,把题目要求的输出格式看清楚——是要打印、要保存文件、还是要返回一个数?格式不符合要求,内容再对也可能扣分。
交卷前的检查清单固定成五条:库是否都导入了、变量名是否前后一致、输出格式是否符合题意、有没有遗漏的 print、随机种子是否设置。这五条覆盖了绝大多数“莫名其妙丢分”的情况。尤其是变量名,写到后面很容易把df1写成data,运行时报 NameError,白白浪费调试时间。
6. 高频混淆点速查与踩坑记录
考前最后一天,我不建议再学新东西,而是翻一遍混淆点清单。下面这张表是我整理的历年最容易被搞混的成对概念,每条都写了区分的关键词。
6.1 概念对照表
| 易混概念 | 区分关键 | 一句话辨析 |
|---|---|---|
| 标准差 vs 标准误 | 描述对象不同 | 标准差描述数据离散,标准误描述样本均值的波动 |
| 总体 vs 样本 | 分母 n 还是 n-1 | 总体方差除以 n,样本方差除以 n-1 |
| 相关 vs 因果 | 是否有干预 | 相关只说明同向变动,因果需要实验或严格设计 |
| 精确率 vs 召回率 | 分母不同 | 精确率分母是预测为正,召回率分母是实际为正 |
| 过拟合 vs 欠拟合 | 训练集表现 | 过拟合训练好测试差,欠拟合两边都差 |
| 参数 vs 超参数 | 谁学的谁设的 | 参数由数据学出,超参数由人预先设定 |
| 分类 vs 聚类 | 有没有标签 | 分类有标签,聚类无标签 |
| 缺失值 MCAR vs MNAR | 缺失是否与值有关 | MCAR 完全随机,MNAR 与缺失值本身相关 |
这张表里我最想强调的是“标准差 vs 标准误”。这两个词在中文里只差一个字,但在统计推断里是完全不同的东西,简答题里一旦混用,整段话的逻辑就崩了。判别口诀:看到“数据的波动”想标准差,看到“均值的精度”想标准误。
6.2 复习与考场阶段的踩坑记录
踩坑一:把数据清洗当成可有可无的前戏。很多人复习时直接跳到建模,觉得清洗就是 dropna 一行代码。实际上综合题一半的分在清洗上,缺失值怎么填、异常值怎么处理、类型怎么转,每一步都要有理由。答题时把理由写出来,比如“用中位数填充,因为该列存在极端值,均值会被拉偏”,这一句话就是分。
踩坑二:公式会背但不会代。计算题给的数据往往不是标准形式,比如给的是分组数据要你先算组中值,或者给的是原始数据要你先排序找中位数。复习时一定要拿笔在纸上算完整流程,光看例题觉得“我会了”,考场上就会发现中间某一步卡住。
踩坑三:忽视题目里的限定词。“简述”“举例说明”“比较异同”是三种不同的答题要求。简述要给定义加要点,举例要真的举一个具体场景,比较要列维度对照。用错答题方式,内容再对也拿不到满分。
踩坑四:复习计划排得太满。我见过有人把每天排到 12 小时,第三天就崩了。比较可持续的节奏是:上午攻 A 档动手练,下午攻 B 档手推公式,晚上花一小时翻 C 档概念,留出半小时做当天回顾。回顾这一步别省,它是把短期记忆转成长期记忆的唯一机会。
踩坑五:只做课内题,不碰真实数据。课内题数据都是干净的、规整的,真实数据是乱的。找一份公开的小数据集自己走一遍完整流程——读入、清洗、分组、画图、建模、评估——你会发现很多课内题不会暴露的问题,比如列名带空格、日期格式不统一、类别值有前后空格。这些问题在综合题里出现的概率很高,提前踩过一次,考场上就是熟路。
最后分享一个我自己带人复习时用的小办法:把整门课的知识点写成 30 张小卡片,正面写概念名,背面写“一句话定义 + 一个例子 + 一个易错点”。每天随机抽 10 张,抽到能完整说出来的就放一边,说不出来的放回待抽堆。三轮下来,剩下的就是真正的薄弱点。这个方法比从头到尾翻笔记高效得多,因为它逼着你主动回忆,而主动回忆的记忆留存率远高于被动阅读。考前一天把剩下的卡片再过一遍,基本就稳了。