news 2026/9/13 3:45:39

Data-Science-For-Beginners 数据准备教程:基于 pandas 的 DataFrame 探查、缺失值与重复数据清洗完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Data-Science-For-Beginners 数据准备教程:基于 pandas 的 DataFrame 探查、缺失值与重复数据清洗完整指南

Data-Science-For-Beginners 数据准备教程:基于 pandas 的 DataFrame 探查、缺失值与重复数据清洗完整指南

【免费下载链接】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 课(数据准备 / Data Preparation)编写,系统讲解如何用 Python + pandas 完成数据清洗的三大核心任务:探查 DataFrame 元信息、处理缺失值(识别、删除、填充)以及去除重复数据。学完本篇,你将掌握info()/head()/tail()isnull()/dropna()/fillna()duplicated()/drop_duplicates()的完整用法与参数细节,并能结合课程配套 Notebook 将清洗流程扩展到真实脏数据的质检场景。

1. 为什么要做数据清洗

根据数据来源不同,原始数据往往包含各种不一致之处,这些问题会在分析与建模阶段带来麻烦。用课程文档(translations/et/2-Working-With-Data/08-data-preparation/README.md,对应英文原文 2-Working-With-Data/08-data-preparation/README.md)的话说:这类数据可以被视为“脏数据”(dirty data),必须被清理。本课聚焦于清洗与转换数据、应对缺失、不准确或不完整数据的技术手段,全部技术点通过 Python 与 pandas 在课程配套 notebook.ipynb 中演示。

课程将数据清洗的价值归纳为三点:

  • 易用与可复用(Ease of use and reuse):数据被妥善组织与规范化后,更容易被检索、使用和与他人共享。
  • 一致性(Consistency):数据科学经常需要同时处理多个数据集,且来自不同来源的数据集必须拼接在一起。确保每个独立数据集都经过统一标准化,才能保证它们合并成一个数据集后依然可用。
  • 模型精度(Model accuracy):清洗过的数据能提升依赖它构建的模型的准确度。

2. 常见的清洗目标与策略

文档总结了四类最常见的清洗目标,它们共同构成了一个数据准备项目的检查清单:

  • 数据集探查(Exploring a dataset):数据探索(详见课程后续章节 4-Data-Science-Lifecycle/15-analyzing/README.md)有助于发现需要被清洗的数据。直观观察数据集中的取值,可以建立对剩余数据形态的预期,或提示可解决的问题。探索手段包括基础查询、可视化与抽样。
  • 格式化(Formatting):取决于来源,数据的呈现方式可能不一致,导致“值在数据集中存在、却无法正确检索或展示”的问题。常见的格式问题包括空白字符(whitespace)、日期与数据类型的处理。格式问题的修复通常由数据的使用方负责,例如日期与数字的表示标准可能因国家而异。仓库中的 data/form.csv 就是一个典型的格式问题样本:同一个月份存在JanuaryJANjanuary三种写法,同一个州存在California/CAFlorida/FL等混用形式——这正是配套作业要处理的真实场景。
  • 重复数据(Duplications):出现多次的数据可能产生不准确的结果,通常应当移除。这在拼接两个或更多数据集时尤为常见。但注意:有些合并后产生的重复行携带额外信息,可能恰恰需要保留。
  • 缺失数据(Missing Data):缺失值会造成不准确、偏弱或有偏的结果。解决方式包括:重新加载数据、用计算与代码(如 Python)填补缺失值、或直接移除该值及其对应的数据。缺失的原因多种多样,采取的补救措施取决于数据是“如何、为何”缺失的。

3. 探查 DataFrame 的基本信息

学习目标:本节结束后,应能自如地从 pandas DataFrame 中查找数据的一般信息。

数据加载进 pandas 后,大概率存放在 DataFrame 中(DataFrame 的完整介绍见前一课 2-Working-With-Data/07-python/README.md)。但如果你的 DataFrame 有 60,000 行、400 列,你该从哪里开始了解手里是什么数据?pandas 提供了便捷工具,可以快速查看 DataFrame 的总体信息以及开头/结尾的若干行。

课程使用 scikit-learn 库中与数据科学绑定的经典数据集——Iris 鸢尾花数据集(英国生物学家 Ronald Fisher 1936 年论文中的测量数据,Notebook 开篇有说明)来演示这些功能:

import pandas as pd from sklearn.datasets import load_iris iris = load_iris() iris_df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])

生成的iris_df前几行如下:

sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2
34.63.11.50.2
45.03.61.40.2

配套 notebook.ipynb 在文档基础上还补充了三个属性级探查工具:

  • DataFrame.shape:属性而非方法(所以不带括号),返回(150, 4),即 150 行 4 列——每行一个观测点、每列一个特征。
  • DataFrame.columns:返回列名Index,本例为sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
  • DataFrame.describe():对数值列给出统计摘要(countmeanstdmin、25%/50%/75% 分位数、max),例如本数据集sepal length (cm)的均值为 5.843333。

文档正文重点展开的三个方法是:

3.1DataFrame.info():查看结构摘要

info()打印 DataFrame 内容摘要。对 Iris 数据集运行iris_df.info(),输出为:

RangeIndex: 150 entries, 0 to 149 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 sepal length (cm) 150 non-null float64 1 sepal width (cm) 150 non-null float64 2 petal length (cm) 150 non-null float64 3 petal width (cm) 150 non-null float64 dtypes: float64(4) memory usage: 4.8 KB

由此可知:Iris 数据集共 150 条记录、4 列,无空值;所有数据均以 64 位浮点数存储。Non-Null Count一栏正是后续缺失值处理的直接入口。

3.2DataFrame.head()DataFrame.tail():查看首尾行

head()查看开头若干行(iris_df.head()返回索引 0–4 的行,数值如 5.1/3.5/1.4/0.2 起始);tail()查看结尾若干行(iris_df.tail()返回索引 145–149 的行,如 6.7/3.0/5.2/2.3 至 5.9/3.0/5.1/1.8)。

结论:仅仅查看 DataFrame 的元数据以及开头/结尾的少数值,就能立即对数据的规模、形状与内容建立直观认知。这是每次接触新数据集的第一动作。

4. 处理缺失值

学习目标:本节结束后,应知道如何从 DataFrame 中替换或移除空值。

你希望使用(或不得不使用)的大多数数据集都含有缺失值。缺失数据的处理方式带有微妙的权衡,会最终影响分析与真实世界结论。

4.1 两种“空值”:NaNNone

pandas 用两种方式表示缺失值:

  • NaN(Not a Number):IEEE 浮点规范中的特殊值,仅用于表示缺失的浮点数值。
  • None:Python 原生对象,用于非浮点类型列的缺失值。

Notebook 用实验演示了两者在底层的关键差异,值得记住:

import numpy as np # None 会把数组升级为 object 类型 example1 = np.array([2, None, 6, 8]) example1 # array([2, None, 6, 8], dtype=object) example1.sum() # TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' # NaN 支持向量化运算,但参与运算的结果仍是 NaN np.nan + 1 # nan np.nan * 0 # nan example2 = np.array([2, np.nan, 6, 8]) example2.sum(), example2.min(), example2.max() # (nan, nan, nan)

从 Notebook 的实现细节看:含None的数组会退化为 Python 对象级解释执行(大数组上会明显变慢),且聚合运算可能直接报错;而含NaN的数组可以正常运行聚合(不报错),但sum()/min()/max()的结果是nan。两种空值各有使用限制,需要在使用时留心。

4.2 识别空值:isnull()/notnull()

pandas中检测空数据的主要方法是isnull()notnull(),两者都返回布尔掩码(Boolean mask):

import numpy as np example1 = pd.Series([0, np.nan, '', None]) example1.isnull()
0 False 1 True 2 False 3 True dtype: bool

请仔细审视这个输出——有没有意外?0虽然是算术上的零,但它是完全合法的正整数,pandas 按整数对待;''更微妙一点:尽管空字符串看起来像“没有东西”,它仍是字符串对象,pandas 不将其视为空值。

反过来用这些掩码更接近实际用法:布尔掩码可以直接作为SeriesDataFrame的索引,当你想隔离缺失(或存在)的值时非常有用。

结论isnull()notnull()DataFrame上产生相似的结果:它们展示掩码结果及其索引,在处理数据时能帮你事半功倍。

4.3 删除空值:dropna()axis/how/thresh参数

除了识别,pandas 还提供了从Series/DataFrame中移除空值的便捷方式(尤其对大数据集,直接移除缺失 [NA] 值通常比其他方式更可取)。回到example1

example1 = example1.dropna() example1
0 0 2 dtype: object

这与example1[example1.notnull()]的筛选输出一致,区别在于dropna直接把缺失值从Series中移除了。

DataFrame有两个维度,因此提供了更多删除选项。构造示例:

example2 = pd.DataFrame([[1, np.nan, 7], [2, 5, 8], [np.nan, 6, 9]])
012
01.0NaN7
12.05.08
2NaN6.09

(注意:pandas 将含NaN的两列自动升级为浮点数类型。)

由于无法只删除 DataFrame 中某个孤立的值,只能删除整行或整列。数据科学中列通常代表变量、行代表观测,所以更常见的操作是删行;dropna()的默认行为就是移除所有含任一空值的行:

example2.dropna()
0 1 2 1 2.0 5.0 8

如需按列删除 NA 值,使用axis='columns'

example2.dropna(axis='columns')
2 0 7 1 8 2 9

这在小数据集上可能删掉大量本应保留的数据。若只想删除含“若干”甚至“全部”空值的行/列,可用howthresh参数控制。dropna默认how='any';改为how='all'则只删除全为空值的行或列。扩展示例(新增全空第 3 列):

example2[3] = np.nan example2
0123
01.0NaN7NaN
12.05.08NaN
2NaN6.09NaN

thresh提供更细粒度的控制:指定一行/一列至少要有多少个非空值才能被保留:

example2.dropna(axis='rows', thresh=3)
0 1 2 3 1 2.0 5.0 8 NaN

这里第 0、2 行因只含 2 个非空值而被删除。

4.4 填充空值:fillna()ffill/bfill

有时用有效值填充空值比删除更合理。你可以用isnull就地实现,但值一多就很繁琐。pandas 因此提供fillna,返回一份缺失值已被替换的Series/DataFrame拷贝。新建示例:

example3 = pd.Series([1, np.nan, 2, None, 3], index=list('abcde')) example3
a 1.0 b NaN c 2.0 d NaN e 3.0 dtype: float64

三种常用填充方式:

# 1) 用单一值(如 0)填充所有空值 example3.fillna(0)
a 1.0 b 0.0 c 2.0 d 0.0 e 3.0 dtype: float64
# 2) 前向填充(forward-fill):用上一个有效值填充 example3.fillna(method='ffill')
a 1.0 b 1.0 c 2.0 d 2.0 e 3.0 dtype: float64
# 3) 后向填充(back-fill):把下一个有效值向前传播 example3.fillna(method='bfill')
a 1.0 b 2.0 c 2.0 d 3.0 e 3.0 dtype: float64

DataFrame用法相同,但还可指定沿哪个轴(axis)填充。再次使用扩展后的example2

example2.fillna(method='ffill', axis=1)
0 1 2 3 0 1.0 1.0 7.0 7.0 1 2.0 5.0 8.0 8.0 2 NaN 6.0 9.0 9.0

注意:当前一行没有可前向填充的值时(第 2 行第 0 列),空值会原样保留。

核心要点:处理数据集缺失值有多种途径。具体策略(删除、替换,乃至用什么方式替换)应由该数据本身的特点决定。与数据集打交道越多,你对缺失值处理的直觉就越成熟。

5. 去除重复数据

学习目标:本节结束后,应能自如地在 DataFrame 中识别并移除重复值。

除缺失值外,真实世界数据集中经常遇到重复数据。pandas提供了检测与移除重复条目的便捷手段。

5.1 识别重复:duplicated()

duplicated方法返回布尔掩码,标明某条DataFrame记录是否是前面某条记录的重复:

example4 = pd.DataFrame({'letters': ['A','B'] * 2 + ['B'], 'numbers': [1, 2, 1, 3, 3]})
lettersnumbers
0A1
1B2
2A1
3B3
4B3
example4.duplicated()
0 False 1 False 2 True 3 False 4 True dtype: bool

5.2 移除重复:drop_duplicates()

drop_duplicates()直接返回一份所有duplicated值均为False的数据拷贝:

example4.drop_duplicates()
letters numbers 0 A 1 1 B 2 3 B 3

duplicateddrop_duplicates默认考虑所有列,但可以指定只检查列的子集:

example4.drop_duplicates(['letters'])
letters numbers 0 A 1 1 B 2

核心要点:去除重复数据几乎是每个数据科学项目的必要步骤。重复数据会改变分析结果、给出错误结论!

6. 从 Notebook 看进阶实践:真实脏数据质检

配套 notebook.ipynb 在 README 主题之外还提供了一个“Real-World Data Quality Checks”章节,把上面的技术扩展到三类更隐蔽的现实问题,值得作为进阶阅读:

  • 不一致的分类值:同一类别存在多种拼写(如USA/U.S.A/United States)。Notebook 演示了先str.lower()再用映射字典标准化的方法,也给出基于rapidfuzz模糊匹配的自动检测方案(process.extract+fuzz.ratio,相似度阈值 70)。
  • 异常数值(离群点):如age = 199-5。Notebook 演示了两种检测手段——基于领域知识的直接过滤(age < 0 or age > 120)、IQR 四分位距法(Q1 - 1.5*IQRQ3 + 1.5*IQR)与 Z-Score 法(scipy.stats.zscore,阈值 3);并总结了四种处理方式:删除、截断到边界、替换为NaN后再填补、保留(若为合法极值)。
  • 近似重复行:先str.strip().str.lower()归一化后用duplicated(subset=..., keep=False)找出所有重复出现项,再用模糊匹配(相似度阈值 90)识别如"John Smith""John Smith"这类近似重复,最后以drop_duplicates(subset=['name_normalized'], keep='first')去重。

Notebook 最终把整套流程封装成一个可复用的清洗管线clean_dataset(df):先df.copy()保护原始数据,再依次标准化分类列、将非法年龄置为NaN、去空白并按归一化名称去重,然后对比清洗前后的行数、唯一国家数与非法年龄数来验证效果。其“Key Takeaways”给出的最佳实践同样适用于任何项目:始终保留原始“脏”数据副本,绝不要覆盖源数据文件,清洗结果另存为data_cleaned.csv一类清晰命名的文件

7. 动手练习与配套资源

  • 完整交互演示:本文所有讲解内容均以 Jupyter Notebook 形式提供在 2-Working-With-Data/08-data-preparation/notebook.ipynb 中,每节之后附有练习题(Exercise),可直接在本地打开运行。
  • 本课作业:assignment.md 布置了“Evaluating Data from a Form”任务——某客户用一个小表单收集客户数据,其中 data/form.csv 就是该表单的 10 条提交记录(月份、州、宠物三个字段,混杂大小写与缩写),你需要运用本课技术找出表单设计问题并给出改进建议;配套练习 Notebook 为 assignment.ipynb。
  • 延伸阅读:缺失值的更多讨论可参考 4-Data-Science-Lifecycle/15-analyzing/notebook.ipynb(NaNNone深入说明);数据探索与深度分析见 4-Data-Science-Lifecycle/15-analyzing/README.md。

小结

数据准备是数据分析与建模前的关键一步,且高度依赖实践。本篇按课程原文脉络给出了一条可复制的清洗主线:先用shape/columns/info()/describe()/head()/tail()摸清数据结构,再用isnull()/notnull()定位缺失、按axis/how/thresh参数化地dropna()、或按常量/ffill/bfill策略fillna(),最后用duplicated()/drop_duplicates()清除精确重复。在此基础上,结合课程 Notebook 的分类值标准化、离群点检测(IQR/Z-Score)与近似重复识别,就能组成覆盖绝大多数“脏数据”场景的完整质检流程。具体采用哪种缺失值或重复值策略,应由数据本身的成因决定——这也是本课题反复强调的判断力训练。

【免费下载链接】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/13 3:45:27

LSTM-Adaboost在电力负荷预测中的优化应用

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

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

Verilog入门:从模块、always到assign的可综合实战

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

作者头像 李华
网站建设 2026/9/13 3:39:34

从NLP到多模态大模型:Transformer架构与跨模态技术解析

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

作者头像 李华
网站建设 2026/9/13 3:39:05

Anaconda完全指南:安装、虚拟环境与PyTorch配置实战

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

作者头像 李华
网站建设 2026/9/13 3:38:48

Zabbix保姆级部署教程:从环境准备到主机接入与报错排查

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

作者头像 李华
网站建设 2026/9/13 3:37:37

CookLikeHOC「调味料(鸡汤专用)」成分拆解与实战应用指南

CookLikeHOC「调味料&#xff08;鸡汤专用&#xff09;」成分拆解与实战应用指南 【免费下载链接】CookLikeHOC &#x1f962;像老乡鸡&#x1f414;那样做饭。已添加2026年发布的《老乡鸡菜品溯源报告 2.0中新出现的菜品。主要部分于2024年完工&#xff0c;非老乡鸡官方仓库。…

作者头像 李华