
第十六章:小项目 2 CSV → 清洗 → 统计 → 图表 → 报告输出
-
- [16.1 本章你将完成什么](#16.1 本章你将完成什么)
- [16.2 项目背景(模拟真实科研场景)](#16.2 项目背景(模拟真实科研场景))
- [16.3 Step 1:读取 CSV(项目级写法)](#16.3 Step 1:读取 CSV(项目级写法))
- [16.4 Step 2:数据初检(必做)](#16.4 Step 2:数据初检(必做))
- [16.5 Step 3:缺失值处理(有原则)](#16.5 Step 3:缺失值处理(有原则))
-
- [16.5.1 学习时间 hours](#16.5.1 学习时间 hours)
- [16.5.2 出勤率 attendance](#16.5.2 出勤率 attendance)
- [16.6 Step 4:异常值处理(科研必须克制)](#16.6 Step 4:异常值处理(科研必须克制))
-
- [16.6.1 发现异常](#16.6.1 发现异常)
- [16.6.2 使用 IQR 规则](#16.6.2 使用 IQR 规则)
- [16.7 Step 5:统计分析(回答问题)](#16.7 Step 5:统计分析(回答问题))
-
- [16.7.1 描述性统计](#16.7.1 描述性统计)
- [16.7.2 相关性分析](#16.7.2 相关性分析)
- [16.8 Step 6:科研级可视化](#16.8 Step 6:科研级可视化)
-
- [16.8.1 学习时间 vs 成绩(散点图)](#16.8.1 学习时间 vs 成绩(散点图))
- [16.8.2 出勤率 vs 成绩](#16.8.2 出勤率 vs 成绩)
- [16.9 Step 7:结果导出(真正的"交付")](#16.9 Step 7:结果导出(真正的“交付”))
-
- [16.9.1 导出清洗后数据](#16.9.1 导出清洗后数据)
- [16.9.2 导出统计摘要](#16.9.2 导出统计摘要)
- [16.10 Step 8:生成分析报告(科研常用套路)](#16.10 Step 8:生成分析报告(科研常用套路))
- [16.11 本章总结(非常重要)](#16.11 本章总结(非常重要))
- 下一章预告
在前面的章节里,我们已经分别掌握了:
- CSV / Excel 的读取与合并
- 缺失值、异常值的处理策略
- 用 Matplotlib 画出能交付的图
但在真实科研或教学评估中,数据分析从来不是"一个函数一个函数地用",而是一条完整、可复现、可解释、可输出的流水线。
这一章,我们用一个完整小项目,把前面学到的内容全部串起来。
16.1 本章你将完成什么
到本章结束,你将能够:
- 从 原始 CSV 文件 出发
- 完成 科研级数据清洗与统计
- 生成 可用于论文 / 汇报的图表
- 输出一份 结构清晰的分析报告(CSV + 图 + Markdown/PDF)
这是一条你以后可以反复复用的"科研模板流水线"。
16.2 项目背景(模拟真实科研场景)
假设你拿到了一份数据:
某课程中,学生的学习行为与最终成绩数据(匿名)
数据文件:student_score.csv
| student_id | hours | attendance | score |
|---|---|---|---|
| S001 | 35 | 0.92 | 88 |
| S002 | NaN | 0.85 | 76 |
| S003 | 12 | 0.40 | 59 |
| S004 | 80 | 0.98 | 95 |
| S005 | 300 | 0.90 | 61 |
科研问题示例:
- 学习时间与成绩是否存在相关性?
- 异常学习行为是否会干扰统计结论?
- 能否给出一份"可交付"的分析结果?
16.3 Step 1:读取 CSV(项目级写法)
python
import pandas as pd
df = pd.read_csv("student_score.csv")
df.head()
科研习惯建议:
- 原始数据只读不改
- 后续所有处理都基于
df_clean
16.4 Step 2:数据初检(必做)
python
df.info()
df.describe()
你需要重点关注三件事:
- 是否有 缺失值
- 是否有 明显异常值
- 数值分布是否"看起来合理"
16.5 Step 3:缺失值处理(有原则)
16.5.1 学习时间 hours
python
df["hours"].isna().mean()
假设缺失比例 < 10%,我们采用 中位数填补:
python
df["hours"] = df["hours"].fillna(df["hours"].median())
原因:学习时间通常右偏分布,中位数更稳健。
16.5.2 出勤率 attendance
python
df["attendance"].isna().sum()
如果无缺失,不处理就是最好的处理。
16.6 Step 4:异常值处理(科研必须克制)
16.6.1 发现异常
python
df["hours"].describe()
如果出现类似:
- max = 300
- 大部分样本 < 80
这是强烈异常信号。
16.6.2 使用 IQR 规则
python
Q1 = df["hours"].quantile(0.25)
Q3 = df["hours"].quantile(0.75)
IQR = Q3 - Q1
upper = Q3 + 1.5 * IQR
python
df_clean = df[df["hours"] <= upper]
注意:科研中不要"悄悄删数据"
👉 你需要在报告中说明:
使用 IQR 方法剔除极端异常学习行为样本
16.7 Step 5:统计分析(回答问题)
16.7.1 描述性统计
python
df_clean[["hours", "attendance", "score"]].describe()
16.7.2 相关性分析
python
df_clean[["hours", "attendance", "score"]].corr()
你此时要开始写结论草稿:
- hours 与 score 是否正相关
- attendance 是否比 hours 更稳定
16.8 Step 6:科研级可视化
16.8.1 学习时间 vs 成绩(散点图)
python
import matplotlib.pyplot as plt
plt.figure(figsize=(6,4))
plt.scatter(df_clean["hours"], df_clean["score"])
plt.xlabel("Study Hours")
plt.ylabel("Score")
plt.title("Study Hours vs Score")
plt.grid(True)
plt.tight_layout()
plt.savefig("hours_vs_score.png", dpi=300)
plt.show()
注意:
- 尺寸可控
- DPI = 300
- 文件名有语义
16.8.2 出勤率 vs 成绩
同样方法,再画一张图。
16.9 Step 7:结果导出(真正的"交付")
16.9.1 导出清洗后数据
python
df_clean.to_csv("student_score_clean.csv", index=False)
16.9.2 导出统计摘要
python
summary = df_clean.describe()
summary.to_csv("summary_statistics.csv")
16.10 Step 8:生成分析报告(科研常用套路)
你至少应包含以下结构(Markdown / Word / PDF):
text
1. 数据来源说明
2. 数据清洗方法
- 缺失值处理策略
- 异常值处理规则
3. 描述性统计结果
4. 相关性分析结论
5. 可视化结果说明
6. 局限性与后续工作
这一步,你已经在做"真正的科研工作"了。
16.11 本章总结(非常重要)
这一章不是教你新函数,而是教你三件决定你科研上限的事:
- 数据分析是一条流水线,不是零散技巧
- 每一步都要"能解释、能复现、能交付"
- 代码只是手段,结论与方法才是科研资产
如果你能熟练完成这一章的小项目------
那么你已经具备了:
把 Python 数据分析写进论文、项目结题和技术报告的能力。