本节摘要:EDA(探索性数据分析)是分析流程里"让数据开口说话"的阶段——通过统计摘要与图表,把数据的分布、异常、关系逐层看清。本节给出 EDA 的四层次流程框架,并配套每层该用的工具与提问方式,让你拿到任何数据集都能有条不紊地开始探索。
阅读完本节,你应当能够:
拿到一张干净的表,接下来干什么?直接建模是危险的——你不知道销售额和什么相关、哪类订单撑起了大盘、数据里藏着什么反直觉的规律。EDA 的价值在于在动手建模之前,先和你的数据混个脸熟:哪些列有故事、哪些关系值得深挖。好的 EDA 能帮你省下后期大量返工。
四层从"整体"到"局部"再到"关系",信息量逐层增加,每层产出"观察 + 疑问",最终汇聚成假设。
import pandas as pd df = pd.read_csv("orders_clean.csv") print(df.shape) df.info() df.describe()
💡 关键直觉:概览的目标不是记住所有数字,而是在心里建立一张表的地图:哪几列是数值、哪几列是类别、大概的量级。后面的探索都基于这张地图展开。
# 数值列:分布与集中趋势 df["金额"].describe() df["金额"].hist(bins=30) # 直方图看分布 # 类别列:频次与集中度 df["门店"].value_counts(normalize=True) # 占比
⚠️ 常见坑:只看
describe()的均值不看直方图,会漏掉"双峰分布"这类重要形状——均值相同的两组数据,分布可能完全不同。数值列务必配合直方图或箱线图。
# 类别 vs 数值:分组箱线图看组间差异 df.boxplot(column="金额", by="门店") # 数值 vs 数值:散点图看关系 df.plot.scatter(x="订单量", y="金额")
corr = df[["金额", "订单量", "折扣"]].corr() print(corr)
相关系数接近 1 表示正相关强、接近 -1 表示负相关强、接近 0 表示无线性关系。看相关矩阵时,对角线永远是 1,重点看非对角线的绝对值。
| EDA 层次 | 统计方法 | 图表 | 回答的问题 |
|---|---|---|---|
| 概览 | info / describe | 无 | 数据长什么样 |
| 单变量-数值 | mean / median / std | 直方图、箱线图 | 分布与异常 |
| 单变量-类别 | value_counts | 条形图 | 类别集中度 |
| 双变量 | 分组统计 | 散点图、分组箱线图 | 变量间关系 |
| 关联 | corr | 热力图 | 谁和谁相关 |
EDA 的终点不是图,而是可检验的假设。比如看到"客单价最高的门店是广州、但销量最高的是北京",可以形成假设:"广州靠大单撑流水,北京靠走量"——这个假设可以在后续分析中用数据验证,也为业务决策提供了方向。
EDA 不是一次性的,它在项目里会出现至少三次:数据刚到手时(了解原材料)、清洗完成后(确认清洗效果)、建模前(为特征工程做准备)。每次的侧重点不同——第一次看"乱不乱",第二次看"净不净",第三次看"哪些特征有用"。把 EDA 当成流程的一部分而不是一次临时探索,是成熟分析者的习惯。
单看全表会掩盖组间差异。加上分组维度,结论往往翻转:
# 全表客单价 print("全表客单价:", df["客单价"].mean()) # 分门店看 print(df.groupby("门店")["客单价"].mean())
全表均值 320,但拆开可能是"北京 250、广州 480"——这种"平均值掩盖组间差异"的现象(辛普森悖论的雏形),只有分组探索才能发现。EDA 里凡是类别列,都值得作为分组键试一遍。
一份好的 EDA 交付物通常包含四块:数据概况(规模、类型、缺失)、关键分布图(每类变量的代表图)、分组对比(维度的差异)、初步结论与假设清单。图表不在多,在每张都回答了一个具体问题。写报告时按"问题 → 图 → 结论"组织,比"图 → 图 → 图"更有说服力。
流程框架有了,下一节上手第一套绘图工具——Matplotlib,把流程图里的每个图表真正画出来。