数据科学生命周期中的分析阶段:用 Pandas 开展探索性数据分析(EDA)实战指南
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
导读
在数据科学生命周期中,分析(Analyzing)阶段承担着承上启下的关键职责:它要验证采集到的数据能否回答业务问题、能否支撑后续建模,是连接"数据采集"与"模型构建"之间的必经桥梁。本篇文章以 Data-Science-For-Beginners 仓库的4-Data-Science-Lifecycle/15-analyzing课程为核心,围绕探索性数据分析(Exploratory Data Analysis, EDA),系统讲解数据画像(Data Profiling)、描述统计、采样(Sampling)、查询(Querying)、可视化探索与缺失值识别的完整方法,并给出基于真实数据集(data/emails.csv与data/taxi.csv)的可复现代码与输出。读完本文,你将掌握用 Pandas 的describe()、sample()、query()、isna()/isnull()等函数对一份陌生数据集进行快速摸底、发现模式与识别问题的完整工作流。
图片来源:本仓库 sketchnotes 目录中由 @nitya 创作的第 15 课手绘笔记,概括了 EDA 的五大步骤:采样、查询、识别离群值/缺失值、可视化、数据画像。
一、为什么"分析"是生命周期中不可跳过的一环
回顾整个数据科学生命周期,采集(Capture)阶段负责获取数据、定义待解决的问题与疑问;但数据到手之后,我们并不能马上确定它能否支撑最终结果。此时就需要进入分析阶段:它确认数据是否能够回答提出的问题或解决特定的问题,同时也关注模型是否正确地响应这些问题。
一个合格的数据科学家在拿到数据后,通常会在心里反复盘问三个问题:
- 我有足够的数据来解决这个问题吗?(数量是否充足)
- 这些数据对于这个问题来说质量是否可接受?(质量是否过关)
- 如果通过数据发现了额外的信息,我们是否应该考虑改变或重新定义目标?(是否需要修正方向)
探索性数据分析(EDA)正是"认识数据"的过程——它既能回答上述三个问题,也能识别处理该数据集时可能遇到的挑战。EDA 通常不预设严格的假设检验框架,而是以开放式的、高密度的快速探索为主,为后续的数据清洗与特征工程提供依据。仓库中本课的配套笔记 notebook.ipynb 即演示了本节介绍的全部 Pandas 函数在邮件数据集上的实际用法,建议跟随其逐格运行。
二、数据画像(Data Profiling)、描述统计与 Pandas
2.1 数据画像与描述统计的分工
如何判断"数据够不够"?这里有两个互补的概念:
- 数据画像(Data Profiling):通过描述统计技术,汇总并收集关于数据集的总体信息,帮助我们理解"我们手头有什么";
- 描述统计(Descriptive Statistics):帮助我们理解"我们有多少"。
简单来说,画像回答"数据长什么样",描述统计回答"数据有多少、分布如何"。两者结合,即可对一份数据集做出第一轮体检。
2.2describe():一条命令完成数据摸底
在之前的多节课中,本课程已经多次使用 Pandas 的describe()函数来获取描述统计。它能够对数值型数据一次性输出:
| 统计指标 | 含义 |
|---|---|
count | 非空样本数量,判断缺失情况的第一手指标 |
mean | 均值,衡量数据集中趋势 |
std | 标准差,衡量离散程度 |
min/max | 最小/最大值,快速发现极值与潜在异常 |
25%/50%/75% | 四分位数,刻画数据分布形态 |
本课使用的示例数据集是来自邮件分类场景的词频数据(存储在 data/emails.csv),每一列代表某封邮件中出现某个常见单词(the、to、and、a、you、i等)的次数。在 notebook.ipynb 中运行:
import pandas as pd # 加载邮件数据集(与笔记本一致:从仓库根目录的 data 目录读取) email_df = pd.read_csv('data/emails.csv') # 对数值列输出描述统计 print(email_df.describe())真实输出(节选)如下:
the to ect and for of count 406.000000 406.000000 406.000000 406.000000 406.000000 406.000000 mean 7.022167 6.519704 4.948276 3.059113 3.502463 2.662562 std 10.945522 9.801907 9.293820 6.267806 4.901372 5.443939 min 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 25% 1.000000 1.000000 1.000000 0.000000 1.000000 0.000000 50% 3.000000 3.000000 2.000000 1.000000 2.000000 1.000000 75% 9.000000 7.750000 4.000000 2.750000 4.750000 3.000000 max 99.000000 88.000000 79.000000 69.000000 39.000000 57.000000 a you in on is this count 406.000000 406.000000 406.000000 406.000000 406.000000 406.000000 mean 57.017241 2.394089 10.817734 11.591133 5.901478 1.485222 std 78.868243 4.067015 19.050972 16.407175 8.793103 2.912473 min 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 25% 15.000000 0.000000 1.250000 3.000000 1.000000 0.000000 50% 29.000000 1.000000 5.000000 6.000000 3.000000 0.000000 75% 61.000000 3.000000 12.000000 13.000000 7.000000 2.000000 max 843.000000 31.000000 223.000000 125.000000 61.000000 24.000000从这份输出可以立刻读出几条重要信息:count均为 406,说明该数据集没有缺失值;而a、i等列的std(约 78.9 / 71.0)远大于mean(约 57.0 / 47.2),且max高达 843 与 754,暗示这些词频分布呈明显的右偏(长尾)形态,存在大量高词频的极端邮件。这些观察会直接影响后续建模时对特征的缩放与变换策略。可见,describe()这种描述统计手段能帮你快速评估"数据有多少、还需不需要补充",并为进一步探查指明方向。
三、采样(Sampling)与查询(Querying)
3.1 为什么要采样
遍历大型数据集中的每一条记录通常非常耗时,这类工作一般交给计算机去完成;但对于人类而言,采样(Sampling)是理解数据的得力工具:通过一个样本,可以结合概率与统计知识对整体数据得出一般性结论。需要特别强调的是:虽然对"应该采样多少数据"没有固定规则,但采样的数据越多,你做出的概括就越精确——样本量始终是采样策略中最核心的权衡点。
3.2sample():随机抽取指定数量的样本
Pandas 提供了sample()函数,你只需传入想要获取的随机样本数量即可:
# 随机采样 10 封邮件查看内容 print(email_df.sample(10))notebook.ipynb 中的真实输出如下(每次运行结果随机):
Email No. the to ect and for of a you in on is this i ... 150 Email 151 0 1 2 0 3 0 15 0 0 5 0 0 7 ... 380 Email 5147 0 3 2 0 0 0 7 0 1 1 0 0 3 ... 19 Email 20 3 4 11 0 4 2 32 1 1 3 9 5 25 ...3.3query():用受控查询验证假设
与采样不同,查询(Querying)允许你对数据保持控制,聚焦于自己产生疑问的具体数据片段,从而回答一般性的问题与假设。Pandas 的query()函数让你以接近自然语言的表达式筛选行,并通过返回的行获取关于数据的直接答案。
例如,若想找出"to出现次数比the还多"的邮件(这类邮件可能是信件类正文而非高频模板):
# 返回 "to" 出现次数多于 "the" 的邮件行 print(email_df.query('the < to'))真实输出显示结果共[169 rows x 17 columns],例如:
Email No. the to ect and for of a you in on is this i ... 1 Email 2 8 13 24 6 6 2 102 1 18 21 13 0 61 ... 3 Email 4 0 5 22 0 5 1 51 2 1 5 9 2 16 ... 405 Email 5172 22 24 5 1 6 5 148 8 23 13 5 4 99 ...在数据集共有 406 封邮件的情况下,有 169 封满足"to多于the",这一比例本身就是有意义的洞察:说明相当一部分邮件的正文风格显著区别于高频模板邮件。query()的价值正在于此——它把"筛选特定子集以检验具体假设、回答一般问题"这件事变成了一行可读性极强的代码。
四、探索中的可视化:不必等数据干净了才开始
很多人会误以为可视化是清洗与分析完成之后才做的事。但本课明确强调:你完全不必等到数据被彻底清洗和分析后再开始创建可视化。事实上,在探索阶段就进行视觉呈现,有助于:
- 识别数据中的模式(patterns)、关系(relationships)与问题(problems);
- 为不参与数据管理的人提供沟通手段;
- 成为分享与澄清"采集阶段未曾提出的新问题"的机会。
例如在邮件数据集上,可以先绘制a列词频的直方图来观察右偏分布;在出租车数据上,可以用散点图直接观察trip_distance与tip_amount的关系。本课程的可视化专项内容位于 3-Data-Visualization 章节,其中讲解了数量、分布、占比、关系等各类图表的选择与绘制方法,可作为 EDA 阶段可视化的进阶参考。
五、探索以识别不一致:缺失值与离群值
本节介绍的所有技术(画像、采样、查询、可视化)都能帮助识别缺失值或不一致的值,而 Pandas 还提供了专门函数用于直接检查:isna()或isnull()均可用于检测缺失值。
# 检查每一列是否有缺失值(返回布尔掩码,True 表示缺失) print(email_df.isna().sum())需要强调的是,探索这些值的真正难点不在于"检测"而在于"溯源":要搞清楚这些值最初为什么会以缺失或不一致的形式出现(是采集遗漏、格式转换失败,还是业务上本就允许为空?)。只有理解了缺失的成因,才能决定采取何种处理行动——这正是数据准备(Data Preparation)阶段的工作范畴,仓库配套的实操笔记位于 2-Working-With-Data/08-data-preparation/notebook.ipynb,其中覆盖了缺失值的删除、填充与插值等处理策略。此外,结合第 2.2 节的describe()输出,若某列的count小于总行数,即可立刻定位到存在缺失的列——这也是画像与缺失检测联动的典型用法。
六、实战作业:在出租车数据上完成你自己的 EDA
6.1 业务问题与数据背景
本课的作业 assignment.md 是上一课(4-Data-Science-Lifecycle/14-Introduction/assignment.md)的延续。客户的问题是:
纽约市黄色出租车乘客在冬季还是夏季给司机的小费更多?
此刻你的团队正处于生命周期的分析阶段,需要对数据集进行探索性数据分析。仓库提供了包含200 条2019 年 1 月(冬季)与 7 月(夏季)出租车交易记录的笔记本与数据:
- 笔记本:assignment.ipynb
- 数据:data/taxi.csv
taxi.csv共 18 列,包含VendorID、tpep_pickup_datetime(上车时间)、tpep_dropoff_datetime(下车时间)、passenger_count(乘客数)、trip_distance(行程距离)、PULocationID/DOLocationID(上下车区域)、payment_type(支付方式)、fare_amount(车费)、tip_amount(小费)、tolls_amount(过路费)、total_amount(总金额)等字段,真实数据形如:
VendorID tpep_pickup_datetime tpep_dropoff_datetime passenger_count trip_distance ... 0 2.0 2019-07-15 16:27:53 2019-07-15 16:44:21 3.0 2.02 1 2.0 2019-07-17 20:26:35 2019-07-17 20:40:09 6.0 1.59 ... 195 2.0 2019-01-18 08:42:15 2019-01-18 08:56:57 1.0 1.18 [200 rows x 18 columns]注意观察数据形态:payment_type为 2(现金支付)的行程tip_amount恒为 0,这本身就是 EDA 阶段会发现的重大线索——支付方式与小费金额高度耦合,直接关系到如何回答季节性问题。
6.2 作业要求与思考路径
在 assignment.ipynb 中运用本节学到的技巧(可自由添加单元格)进行你自己的 EDA,并回答以下三个问题:
- 数据中还有哪些其他因素可能影响小费金额?(可考察
trip_distance、passenger_count、payment_type、fare_amount、时段/星期等;建议用describe()查看各列分布,用query()按支付方式筛选,用sample()抽查原始记录) - 哪些列最可能对回答客户问题没有帮助?(例如
VendorID、store_and_fwd_flag等标识性/技术性字段往往与"季节 vs 小费"关系不大) - 基于目前提供的信息,数据是否提供了季节性小费行为的任何证据?(通过比较 1 月与 7 月的
tip_amount分布得出结论,并可辅以可视化佐证)
作业提供了"杰出 / 合格 / 需改进"三档评分标准(Rubric),核心考察点在于是否系统性地运用了本课的 EDA 技术链。完成它,就相当于把describe()、sample()、query()、缺失检查与可视化完整地串成了一条可复用的分析流水线。
七、小结:一节课读懂 EDA 的完整工具箱
分析阶段是数据科学生命周期中验证"数据是否可用"的关键节点,而 EDA 则是其方法论核心。本课围绕五个互为补充的技术维度展开:
| 技术 | 关键 Pandas 函数 | 解决的问题 |
|---|---|---|
| 数据画像 / 描述统计 | describe() | 数据有什么、有多少、分布形态如何 |
| 采样 | sample() | 用随机子集快速理解整体 |
| 查询 | query() | 受控地筛选子集、检验具体假设 |
| 可视化探索 | matplotlib / seaborn 等 | 发现模式、关系与问题(进阶见 3-Data-Visualization) |
| 不一致识别 | isna()/isnull() | 定位缺失值,并为后续处理溯源(处理见 08 数据准备) |
在实际项目中,这五项技术往往是交叉使用的:先用describe()建立整体画像,再用sample()抽查原始形态,用query()验证特定假设,用可视化确认模式,最后用缺失检查收尾。掌握这套工作流,你就能在任何新数据集面前快速回答"数据能否支撑我的问题"这一生命周期中的核心命题。
【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考