4-2 DataFrame基本与数据清洗
📌 一、 课程导入(10 分钟)
- 真实场景痛点:拿到的数据能直接喂给机器学习模型吗?
- 上节课我们学会了把 CSV 读进 DataFrame,但现实中的原始数据充满了“垃圾”:有缺失的空项、重复录入的行、杂乱的文本分类(如“男/女”、“北京/上海”)。
- 计算机模型只认识数字,且极度害怕
NaN(空值)。
- 数据预处理的两大核心任务
- 任务一:数据切片与组装(怎么把想要的数据筛选出来?怎么把多张表拼在一起?)
- 任务二:数据清洗与特征打磨(去重、补缺、数值化,打造适合模型的干净矩阵)。
- 👨🏫 教师活动:展示一张带有
NaN和文本分类的真实二手房数据集,提出问题:“如果不处理直接让模型计算房价,会发生什么?” - 🧑🎓 学生活动:思考并回答问题,意识到必须先对数据进行清洗和转换,才能进行后续的数学建模。
从真实数据集的“脏乱差”痛点切入,明确本节课的核心任务,帮助学生建立从“表格操作”到“模型输入预处理”的工程桥梁。
📖 二、 解决问题过程(一):DataFrame 基本操作——检索、排序与合并(30 分钟)
1. 精准定位:loc(看名字)vs iloc(看数字)
loc[行标签, 列标签]:基于显式名称定位。iloc[行位置, 列位置]:基于隐式数字序号定位(左闭右开,与 NumPy 一致)。
2. 布尔筛选(条件过滤)与排序
-
筛选语法:
df[条件表达] -
单条件:
df[df['售价'] > 300] -
多条件(必须用
&或|,且每个条件必须加小括号):df[(df['售价'] > 300) & (df['面积'] > 100)] -
排序:
df.sort_values(by='列名', ascending=False)(ascending=False表示降序)。
3. 表合并:concat 与 merge
pd.concat([df1, df2], axis=0):简单拼接(axis=0纵向按行堆叠,axis=1横向按列拼接)。pd.merge(df1, df2, on='主键', how='inner'):按共同字段精准关联(类似 SQL Join)。
- 👨🏫 教师活动:重点演示布尔筛选时“漏写括号”引发的经典语法错误,帮助学生规避;用图解演示
merge的inner与left关联机制。 - 🧑🎓 学生活动:在 Jupyter Notebook 中跟练代码,尝试编写多条件筛选语句,提取符合特定条件的行。
掌握数据检索与合并是数据预处理的基本功,通过对比 loc/iloc 以及强调布尔括号规则,提升学生的代码准确度。
💻 三、 解决问题过程(二):数据清洗“四大件”与特征转换(30 分钟)
1. 缺失值处理(NaN 清洗)
- 检查缺失值:
df.isna().sum()(统计每列空值数量)。 - 删除空值行:
df.dropna(axis=0)。 - 填补空值(更常用):
df['列名'].fillna(值, inplace=True)(如用均值/中位数填补)。
2. 重复数据处理
- 检查重复行:
df.duplicated()。 - 删除重复行:
df.drop_duplicates(inplace=True)。
3. 连续特征离散化(分箱 pd.cut)
将连续数字(如年龄、房价)切分成区间段(如:青年/中年/老年)。
- 语法:
pd.cut(df['面积'], bins=[0, 70, 110, 200], labels=['小户型', '中户型', '大户型'])
4. 哑变量处理(One-Hot 独热编码 pd.get_dummies)
机器学习核心预处理:将文本分类变量(如“朝向: 东/南/西”)转换为计算机可识别的 0/1 矩阵。
- 👨🏫 教师活动:画图演示 One-Hot 独热编码是如何把一列文本转换为多列 0/1 矩阵的;带领学生一步步完成“去重 ➔ 补缺 ➔ 分箱 ➔ 哑变量”组合拳。
- 🧑🎓 学生活动:观察转换后
clean_df的列数变化,理解为什么哑变量处理会导致特征列数增多,并在 Jupyter 中跟练。
打通从“脏表格”到“机器学习可用数值矩阵”的最后一步;将离散化与哑变量这两个看似抽象的概念,用极简的代码和真实表格演示呈现。
✍️ 四、 解决问题过程(三):充分课堂练习与巩固(20 分钟)
📝 五、 课堂小结(5 分钟)
flowchart LR
root["📊 4-2 DataFrame 操作与清洗预处理"]
subgraph C1["🔍 1. 检索与拼接"]
direction TB
A1["loc (看名字) / iloc (看数字)"]
A2["布尔筛选: df[(条件1) & (条件2)]"]
A3["合并: concat / merge"]
end
subgraph C2["🧹 2. 数据清洗"]
direction TB
B1["去重: drop_duplicates()"]
B2["补缺: dropna() / fillna()"]
B3["诊断: isna().sum()"]
end
subgraph C3["⚙️ 3. 特征转换"]
direction TB
C1_node["分箱离散化: pd.cut()"]
C2_node["独热编码: pd.get_dummies()"]
C3_node["成果: 转化纯数值矩阵"]
end
root --> C1
root --> C2
root --> C3
%% 自定义主题色彩美化
style root fill:#4b6cb7,stroke:#253b6e,color:#fff,stroke-width:2px,rx:8px,ry:8px
style C1 fill:#e3f2fd,stroke:#2196f3,stroke-width:1px
style C2 fill:#fff3e0,stroke:#ff9800,stroke-width:1px
style C3 fill:#e8f5e9,stroke:#4caf50,stroke-width:1px