news 2026/9/14 15:50:54

Data-Science-For-Beginners 表单数据评估实战:用 Pandas 诊断与清洗客户表单采集数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Data-Science-For-Beginners 表单数据评估实战:用 Pandas 诊断与清洗客户表单采集数据

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 第 8 课配套练习「Evaluating Data from a Form(评估表单数据)」展开:一位客户用一个小型 HTML 表单采集了客户基础信息,交付你验证数据质量、定位可视化结果异常的原因,并给出表单改进建议。读完本文,你将掌握用 pandas 检查缺失值、统一格式、去重等清洗手段,并能够把「数据入口设计」与「数据清洗」结合起来,从源头提升采集数据的准确性与一致性。

任务背景:客户表单与待验证的数据

表单结构

客户部署的表单是一个极简静态页面 index.html,浏览器直接打开即可查看。从源码看,它只包含三个采集字段:

<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>

值得注意的三个细节:

  • **Birth Month(出生月份)**用自由文本框输入,虽然标了*(必填),但没有任何格式约束;
  • **State(州)**同样是自由文本,且未标记必填;
  • Dogs or Cats?是下拉框,选项value为小写复数"dogs"/"cats",而页面显示文本为"Dog"/"Cats",值与标签的约定并不一致。

这些「看起来无关紧要」的设计差异,正是后续数据问题的源头,也是本次评估任务的核心线索。

待验证的数据集

客户提供了表单记录的 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

肉眼扫一遍即可发现大量「脏数据」特征:月份大小写混用(January/JAN/january)、缩写与全称混用(SeptvsSeptember)、州名缩写与全称混用(CAvsCaliforniaFLvsFlorida)、空值(第一条记录的 state 为空)等。

练习要求与评估标准

原练习文档要求如下(原文来自 translations/fr/2-Working-With-Data/08-data-preparation/assignment.md,英文原版见 assignment.md):

Instructions(任务要求):运用本课(Data Preparation)讲授的技术,就如何改进表单、使其能够采集到准确且一致的信息,提出你的建议。

练习配套的评估表格(Rubric)给出了三个维度:

Exemplary(优秀)Adequate(合格)Needs Improvement(需改进)
完整识别出数据质量问题并逐一给出代码级修复方案,同时能指出表单设计层面的根源并提出可落地的改进建议识别出大部分质量问题并给出部分处理建议仅指出少量问题,或缺乏可操作的修复建议

结合练习说明,交付物应包含:① 对数据集质量问题的诊断;② 解释可视化为何「看起来不正确」;③ 基于 pandas 的清洗/标准化方案;④ 对表单本身的改进建议。

第一步:加载数据并探查

练习提供的 assignment.ipynb 已经给出了加载数据与绘制可视化的骨架。核心代码为:

import pandas as pd import matplotlib.pyplot as plt # 加载数据集(相对于仓库根目录的路径) path = 'data/form.csv' form_df = pd.read_csv(path) print(form_df)

运行后输出与 notebook 内记录的结果一致:

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

课程 README(2-Working-With-Data/08-data-preparation/README.md)中强调,面对任何数据集,第一步都是探查:通过元信息快速建立对数据规模、结构与内容的整体认知,再做进一步判断。常用手段包括:

form_df.shape # (10, 3),10 行 3 列 form_df.info() # 各列类型、非空计数与内存占用 form_df.head() # 前 5 行 form_df.tail() # 后 5 行 form_df.describe() # 数值列的统计摘要(本例全为文本列,作用有限)

对这份数据来说,info()会立即暴露问题:state列存在非空计数少于总行数的情况(因为 CSV 中的空字段被 pandas 自动解析为NaN),这正是「缺失值」的第一信号。

第二步:诊断数据质量问题的根源

对照课程 README 归纳的常见清洗目标(格式统一重复值缺失值探索性观察),本数据集存在的问题可逐项归类。

月份字段:大小写与缩写不一致

birth_monthJanuary出现了三次,但写法分别是JanuaryJANjanuarySeptSeptember实为同一个月。也就是说,同一月份在数据集中被拆成了多个互不相同的字符串

州字段:缺失值 + 缩写/全称混用

state列第一条记录为空(NaN),同时CACalifornia指向同一个州,FLFlorida同理。若按原始字符串做统计,同一个州会被拆成两个类别。

宠物字段:值与标签约定不一致

pet列只出现CatsDog两种值,但它们既不是表单value中的小写复数(dogs/cats),也不是统一的大小写/单复数约定——Cats是复数而Dog是单数。若不同批次的数据分别按「标签」和「值」落库,后续合并必然产生新类别。

可视化为什么「看起来不正确」

练习中客户报告「部分可视化看起来不对」。原因并不在绘图本身,而在数据:value_counts()是按字符串精确相等分组的。课程 Notebook(2-Working-With-Data/08-data-preparation/notebook.ipynb)中的实践也印证了这一点——对脏的分类列直接做计数,等价于把同一实体的不同拼写当成不同类别:

form_df['state'].value_counts().plot(kind='bar') plt.show() form_df['birth_month'].value_counts().plot(kind='bar') plt.show()

于是birth_month的柱状图上会出现三个并排的January/JAN/january柱子,state图上会出现两个并排的CA/California柱子——客户眼中「不对」的图,根源是数据未标准化,而不是代码有 bug。

第三步:用 Pandas 清洗表单数据

以下操作全部对应课程 README 与 Notebook 中讲解的核心 API,可直接在 assignment.ipynb 或独立 Python 环境中复现。

3.1 检测缺失值:isnull/notnull

课程指出,pandas 用NaN(IEEE 浮点规范中的特殊值)表示缺失浮点值,用 Python 的None表示其余类型的缺失,而isnull()/notnull()是检测两者的主要手段,返回布尔掩码:

form_df.isnull() # 逐元素布尔掩码 form_df.isnull().sum() # 每列缺失数量:state 列有 1 个 form_df.notnull() # 与 isnull 互补

需要注意(课程 Notebook 中的例子):0是合法整数而非缺失;空字符串''在 pandas 看来同样是合法的字符串对象,不是缺失值。本数据集中state的空单元格之所以被识别为NaN,是因为read_csv在解析时就把空字段转成了缺失值。

3.2 处理缺失值:dropna/fillna

课程提供了两种策略。一是删除,用dropna()

form_df.dropna() # 默认 how='any':删除含任一缺失值的行 form_df.dropna(axis='columns') # 按列方向删除 form_df.dropna(how='all') # 仅当整行全为缺失时才删除 form_df.dropna(thresh=3) # 保留非空值数量 >= 3 的行 form_df.dropna(subset=['state']) # 仅依据指定列判断缺失

二是填充,用fillna(),可以填固定值、前向填充或后向填充:

form_df.fillna('Unknown') # 用固定值填充 form_df.fillna(method='ffill') # 前向填充:用上一个有效值填补 form_df.fillna(method='bfill') # 后向填充:用下一个有效值填补

兼容性提示:课程材料沿用fillna(method='ffill')的写法;在较新版本的 pandas 中该方法已被弃用,推荐改用等价的df.ffill()df.bfill()

3.3 标准化分类值:映射字典 + 字符串方法

针对大小写与缩写混用,课程 Notebook 给出的做法是「先统一字符串形式,再用映射字典标准化」——这也是本练习最核心的修复步骤。以下代码针对birth_monthstatepet三列分别处理:

# 月份:统一为「首字母大写的完整月份名」 month_mapping = { 'jan': 'January', 'feb': 'February', 'mar': 'March', 'apr': 'April', 'may': 'May', 'jun': 'June', 'jul': 'July', 'aug': 'August', 'sep': 'September', 'oct': 'October', 'nov': 'November', 'dec': 'December', } def normalize_month(v): if pd.isnull(v): return v s = str(v).strip().title() # 'JAN' -> 'Jan','sept' -> 'Sept' return month_mapping.get(s[:3].lower(), s) form_df['birth_month_clean'] = form_df['birth_month'].apply(normalize_month) # 州:缩写与全称统一为两字母大写缩写(示例节选,可按需补全 50 州) state_mapping = { 'alaska': 'AK', 'california': 'CA', 'florida': 'FL', 'hawaii': 'HI', 'rhode island': 'RI', } def normalize_state(v): if pd.isnull(v): return v s = str(v).strip().lower() if len(s) == 2: # 已是缩写,统一大写 return s.upper() return state_mapping.get(s, v) form_df['state_clean'] = form_df['state'].apply(normalize_state) # 宠物:统一为小写复数,与表单 <select> 的 value 约定保持一致 def normalize_pet(v): if pd.isnull(v): return v s = str(v).strip().lower() return {'dog': 'dogs', 'cat': 'cats'}.get(s, s) form_df['pet_clean'] = form_df['pet'].apply(normalize_pet)

标准化之后再统计,柱子数量才会与真实类别数一致:

form_df['birth_month_clean'].value_counts() # January 现在只有一根柱子 form_df['state_clean'].value_counts() # CA 与 California 合并为一类

对于更复杂的拼写差异,课程 Notebook 还演示了用rapidfuzz库做模糊匹配(相似度高于 70% 即提示为近义名称),适合拼写变体多、难以穷举映射表的场景,可参考 notebook.ipynb 中的「Detecting Inconsistent Categorical Values」一节。

3.4 检测与删除重复值:duplicated/drop_duplicates

课程指出,重复数据会扭曲统计结果、产生不准确的分析,通常应删除;但在多数据集合并时,部分「重复」行可能携带补充信息,需具体判断。检测与删除接口如下:

form_df.duplicated() # 布尔掩码,标记与更早行重复的行 form_df.duplicated().sum() # 完全重复的行数 form_df.drop_duplicates() # 删除完全重复行 form_df.drop_duplicates(subset=['pet']) # 仅依据指定列判断重复

本数据集中虽然没有完全相同的行,但存在近重复行:第 0 行(January,缺州,Cats)与第 7 行(JanuaryCaliforniaCats)在月份与宠物上完全一致,仅州字段一缺一全——这正是课程 Notebook「Detecting Near-Duplicate Rows」一节针对的场景。可以先做 3.3 的标准化,再按关键列检测近重复:

form_df[form_df.duplicated(subset=['birth_month_clean', 'pet_clean'], keep=False)]

对这类近重复行,建议与客户确认是否同一用户重复提交,再决定去重或保留。

3.5 参考:完整的清洗流水线

课程 Notebook 在末尾提供了一个可直接复用的「脏数据 → 干净数据」流水线示例(创建示例脏数据集后依次执行三步):1. 检测不一致的分类值并标准化(映射字典 / 模糊匹配);2. 检测异常数值(离群点)3. 检测近重复行。本练习的数据集为纯分类字段,暂不涉及数值离群点,但若后续表单增加年龄、金额等数值字段,可直接套用该流水线的离群点检测逻辑,详见 notebook.ipynb 末尾的「Creating a Sample 'Dirty' Dataset」一节。

第四步:从源头改进表单设计

课程 README 强调,清洗的最终目标不仅是修好一份数据,更是保证「易用与复用、跨数据集的一致性、模型准确性」。因此本练习的落点应是建议客户改进表单本身,从源头避免脏数据。结合 index.html 的现状,可给出如下可落地建议:

  • Birth Month:将自由文本框替换为 12 个固定月份的<select>下拉框(或用日期选择器),彻底消除大小写与缩写差异;required属性保持必填语义。
  • State:替换为包含 50 个两字母州缩写(CAFL等)的下拉框,禁止自由文本,从机制上杜绝「缩写 vs 全称」混用。
  • Pets:统一value与显示标签的约定(例如value="dogs"配标签Dogs),并保证入库值使用value而非显示文本,避免单复数/大小写漂移。
  • 校验兜底:为文本类字段补充 HTML5requiredpatternmaxlength等约束;后端入库前再做一次字符串strip()title()/upper()归一化,作为第二道防线。
  • 口径文档化:在表单页或数据字典中明确每个字段的取值标准,方便后续团队跨数据集合并时保持一致性(对应课程强调的「Consistency」目标)。

评分建议与自查清单

  • 优秀(Exemplary):能同时给出 ① 数据质量诊断(缺失、格式、重复、近重复);② 可视化异常的解释(value_counts按精确字符串分组);③ 可运行的 pandas 清洗代码;④ 指向表单源码的具体改进建议。
  • 合格(Adequate):识别出大部分问题并给出代码或表单层面的处理建议。
  • 需改进(Needs Improvement):仅罗列现象、缺乏根因分析与可操作方案。

延伸学习

  • 课程主文档:2-Working-With-Data/08-data-preparation/README.md(清洗的意义、缺失值/重复值处理的完整讲解)
  • 配套 Notebook:2-Working-With-Data/08-data-preparation/notebook.ipynb(含脏数据流水线示例与课后练习)
  • 数据探查与后续分析:4-Data-Science-Lifecycle/15-analyzing/README.md
  • pandas 基础(DataFrame 概览):2-Working-With-Data/07-python/README.md
  • 练习文件:assignment.ipynb、表单页、数据集

【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 15:49:38

基于STM32的图书馆环境监测系统设计与仿真

1. 项目概述&#xff1a;为什么要给图书馆做一套环境监测系统做嵌入式这些年&#xff0c;手上过过不少板子&#xff0c;从51到MSP430再到STM32&#xff0c;真正让我觉得"既有教学价值又有实际意义"的开源小项目&#xff0c;图书馆环境监测系统算是一个很典型的存在。…

作者头像 李华
网站建设 2026/9/14 15:48:19

国产AI芯片五条技术路线实战指南:架构、生态与适配

1. 为什么说“一条路跑不下”——国产AI芯片的底层逻辑困局 “国产 AI 芯片&#xff0c;一条路跑不下&#xff0c;五条路线并行”——这句话不是修辞&#xff0c;是2024年真实产业现场的切口式诊断。我从2018年起参与多个国产算力平台的适配落地项目&#xff0c;从早期在昇腾91…

作者头像 李华
网站建设 2026/9/14 15:47:28

Kubernetes安全认证机制详解与实践指南

1. Kubernetes安全认证机制概述在云原生环境中&#xff0c;Kubernetes作为容器编排的事实标准&#xff0c;其安全性设计至关重要。认证、授权和准入控制&#xff08;简称AAA&#xff09;构成了Kubernetes安全体系的三大支柱&#xff0c;它们像安检系统的三道关卡一样层层递进&a…

作者头像 李华
网站建设 2026/9/14 15:47:09

Unity小游戏热更实战:HybridCLR+YooAsset框架搭建与踩坑记录

做小游戏的朋友应该都有体会&#xff0c;微信小游戏、抖音小游戏这些平台天然就有包体限制和首包限制&#xff0c;动不动就没法把资源怼进包里。再加上 iOS 平台对代码热更的强约束&#xff0c;很多团队在设计 Unity 小游戏方案时第一个被卡住的点就是&#xff1a;游戏上线以后…

作者头像 李华
网站建设 2026/9/14 15:45:42

STM32CubeProgrammer安装与使用:嵌入式AI开发烧录工具链完全指南

干嵌入式的人大概都有过这种体验&#xff1a;代码写得正爽&#xff0c;AI也帮你把外设驱动、状态机、协议栈全安排得明明白白&#xff0c;结果到了最后一步&#xff0c;卡在了烧录上。开发板连上电脑&#xff0c;IDE里一顿报错&#xff0c;target not found、driver not instal…

作者头像 李华
网站建设 2026/9/14 15:45:06

Dify 1.17 部署实战:从环境准备到模型接入与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华