Data-Science-For-Beginners 实战:用 pandas 数据清洗技术评估并修复表单数据质量问题
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
本篇技术指南围绕 Data-Science-For-Beginners 仓库中「数据准备(Data Preparation)」一课的课后任务展开:客户用一份极简 HTML 表单收集了 10 条客户记录,但其中混入了大小写不一致、月份缩写、州名缩写与全称混用、缺失值等典型“脏数据”,导致基于value_counts()绘制的可视化出现错误分类。读完本文,你将掌握用 pandas 探查数据、定位脏数据模式、制定清洗策略,并最终反推表单设计缺陷、给出可落地的表单改造建议的完整实战流程。
任务背景:一份“脏”表单与其数据集
本任务是「Working with Data」第 08 课 数据准备课程 README 的课后作业。客户正在测试一个小型表单来收集客户基本信息,他们把收集结果交给了我们,要求验证数据质量,并针对表单本身给出改进建议。
表单结构
打开 index.html 可以看到,表单共 3 个字段,全部使用自由文本输入(仅宠物字段是下拉框):
<h1>Please Fill out the Form (* required)</h1> *<label>Birth Month</label> <input type="text"> <br> <label>State</label> <input type="text"> <br> <label for="pets">Dogs or Cats?</label> <select name="pets" id="pets"> <option value="dogs">Dog</option> <option value="cats">Cats</option> </select> <br> <button>Submit</button> </body>从源码可以看出两个隐患:Birth Month与State都是type="text"的自由输入框,Birth Month甚至标记了* required却没有实际启用 HTML 的required属性。自由文本输入意味着用户可以用任意格式填写,这正是数据质量问题的根源。
数据集:10 条客户记录
data/form.csv 保存了表单提交的 10 条记录,共 3 列:
birth_month,state,pet January,,Cats JAN,CA,Cats Sept,Hawaii,Dog january,AK,Dog July,RI,Cats September,California,Cats April,CA,Dog January,California,Cats November,FL,Dog December,Florida,Cats评估目标
根据 任务文档 与 任务 Notebook 的说明,任务要求我们:
- 打开
index.html在浏览器中查看表单; - 检查
form.csv中来自表单的 CSV 记录及基础可视化; - 客户指出部分可视化看起来不正确,但不知道如何解决;
- 使用本课的技术对表单提出建议,使其能够收集准确、一致的信息。
快速上手:加载数据并复现“错误的可视化”
任务 Notebook 的第一步是安装并引入依赖、加载数据:
import pandas as pd import matplotlib.pyplot as plt # 加载数据集 path = 'data/form.csv' # 原 notebook 中为 '../../data/form.csv' form_df = pd.read_csv(path) print(form_df)输出如下(与 assignment.ipynb 第 4 个代码单元格的记录一致):
birth_month state pet 0 January NaN Cats 1 JAN CA Cats 2 Sept Hawaii Dog 3 january AK Dog 4 July RI Cats 5 September California Cats 6 April CA Dog 7 January California Cats 8 November FL Dog 9 December Florida Cats紧接着,任务 Notebook 用value_counts()分别对state与birth_month绘制了条形图:
form_df['state'].value_counts().plot(kind='bar') plt.show() form_df['birth_month'].value_counts().plot(kind='bar') plt.show()这正是“看起来不正确”的可视化。因为value_counts()是按字符串原文分类计数的,所以它会把CA和California当作两个不同的州、把JAN、January、january当作三个不同的月份分别计数,导致条形图出现大量“虚假分类”,完全无法反映真实的数据分布。
问题诊断:三类典型数据质量问题
对照课程 README 中归纳的清洗目标,这份数据同时命中了格式化(Formatting)、缺失数据(Missing Data)两类问题。
1. 格式不一致:月份列
birth_month列的 10 条记录里,同一月份出现了多种写法:
| 实际月份 | 出现的写法 | 记录数 |
|---|---|---|
| January | January、JAN、january | 4 |
| September | Sept、September | 2 |
| July | July | 1 |
| April | April | 1 |
| November | November | 1 |
| December | December | 1 |
问题具体表现为:
- 大小写不统一:
Januaryvsjanuary; - 缩写与全称混用:
JAN(三字母缩写)、Sept(截断式缩写)vsJanuary等全称。
这些写法在视觉和字符串层面都不相等,导致value_counts()将它们拆分为 9 个独立类别(实际只有 6 个月份)。
2. 格式不一致:州名列
state列同样是缩写与全称混用:
| 实际州 | 出现的写法 | 记录数 |
|---|---|---|
| California | CA、California | 3 |
| Florida | FL、Florida | 2 |
| Hawaii | Hawaii | 1 |
| Alaska | AK | 1 |
| Rhode Island | RI | 1 |
3. 缺失数据:州名缺失
第 0 行记录的state为NaN(Not a Number)。在 pandas 中,缺失值以NaN(IEEE 浮点规范中的特殊值,用于表示缺失的浮点值)或 Python 的None表示,课程 notebook.ipynb 对此有详细讲解。这份 CSV 中缺失的state被 pandas 解析为NaN,属于典型的缺失数据。
对比之下,pet列只有Cats与Dog两种取值(来自下拉框),完全一致——这从侧面印证了自由文本输入是数据脏乱的主因,而下拉框天然约束了取值范围。
数据清洗实战:用 pandas 还原真实分布
课程 notebook.ipynb 与 README 提供的核心清洗武器包括:探查(head/tail/info)、缺失值处理(isnull/notnull/dropna/fillna)、去重(duplicated/drop_duplicates)。下面我们用这些技术清洗表单数据。
第一步:探查缺失情况
form_df.isnull().sum()输出表明只有state列有 1 个缺失值。isnull()返回布尔掩码,直接对掩码sum()即可统计各列缺失总数——这是 notebook 中“example3.isnull().sum()”模式的直接应用。
第二步:标准化月份列
把大小写统一,并将JAN、Sept等缩写映射到规范全称:
month_map = {'JAN': 'January', 'Sept': 'September'} form_df['birth_month'] = ( form_df['birth_month'] .str.title() # JAN -> Jan, january -> January .replace(month_map) # Jan -> January, Sept -> September )清洗后birth_month的分布为:January 4、September 2、July 1、April 1、November 1、December 1,条形图恢复真实分布。
第三步:标准化州名列
建立“缩写 → 全称”映射统一州名:
state_map = { 'CA': 'California', 'AK': 'Alaska', 'RI': 'Rhode Island', 'FL': 'Florida', } form_df['state'] = form_df['state'].replace(state_map)清洗后:California 3、Florida 2、Hawaii 1、Alaska 1、Rhode Island 1、缺失 1。
第四步:处理缺失值
对state的缺失值有两种选择:
- 删除(
dropna()):数据集很小时会损失样本,但实现最简单; - 填充(
fillna()):例如填充为'Unknown'或众数,保留样本但引入人为取值。
form_df.dropna() # 删除含缺失值的行 form_df['state'].fillna('Unknown') # 或用占位值填充选择依据(课程反复强调):具体策略应由数据的具体情况决定。对本任务而言,更推荐在修复表单后重新收集数据,避免“事后补值”。
第五步:检查重复记录
课程还强调重复数据会改变分析结果。可验证本数据集是否存在重复提交:
form_df.duplicated() # 逐行布尔掩码 form_df.drop_duplicates() # 返回去重副本根因修复:表单设计建议
数据清洗治标,表单改造治本。对照 index.html 源码,针对已诊断出的问题,可给出以下可落地的建议:
建议一:用下拉框/单选控件替代自由文本输入
Birth Month与State字段应仿照pet字段(<select>下拉框)改为受限选择:
- 月份:提供 12 个选项的下拉框(
January~December),彻底杜绝缩写与大小写问题; - 州名:提供 50 个州全称(或统一的两位缩写)的下拉框,杜绝
CA/California混用。
这是从数据源头保证一致性的最直接手段,也正是课程 README 中“格式化问题通常取决于使用者”的实践注解——把格式化决策前置到表单层。
建议二:启用必填校验
Birth Month虽标注了* required,但 HTML 源码并未添加required属性。应补上:
<label>Birth Month</label> <select name="birth_month" required> <option value="">-- Select --</option> ... </select> <label>State</label> <select name="state" required> <option value="">-- Select --</option> ... </select>同时可在前端用pattern校验、后端做兜底校验,从源头减少缺失数据(本例state的NaN即因未填而提交)。
建议三:统一存储与展示格式
即使保留自由输入,也应在提交时做规范化(如str.title()+ 缩写映射),或在收集端提供示例占位符,确保入库即标准格式。
评估标准与验收
任务文档给出了三档评价标准,可用于自查交付质量:
| 优秀(Exemplary) | 达标(Adequate) | 待改进(Needs Improvement) |
|---|---|---|
| 完整定位三类数据问题,给出清洗后的正确分布,并对表单提出可直接落地的改造(下拉框、必填校验等) | 能识别主要问题并提出部分建议,但清洗或建议不完整 | 仅描述现象,未定位根因,未给出可执行的表单改进方案 |
仓库参考资源
- 任务文档(英文原版):任务说明与评价标准
- 任务 Notebook:数据加载与可视化复现
- 课程 README:清洗重要性、格式化、去重、缺失值理论
- 课程 Notebook:
info/head/tail、isnull/notnull/dropna/fillna、duplicated/drop_duplicates的完整代码示例 - 表单页面 与 表单数据:任务数据源
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考