4. 探索性数据分析(EDA):描述性统计与数据分布可视化

各位同学,欢迎来到第四章。前面我们讲了数据清洗,把脏数据都收拾干净了。现在,我们要开始真正「看」数据了。

EDA,探索性数据分析,说白了就是跟数据「混个脸熟」。你想想看,拿到一堆电力能耗数据,几万行、几十万行,你不可能一行行去读。那怎么办?用统计指标和图表,让数据自己「说话」。

我个人习惯,做任何分析之前,先做两件事:算描述性统计画分布图。这两步走完,数据的大致脾气你就摸透了。

4.1 描述性统计:用数字「速写」数据

描述性统计,就是用几个关键数字,快速概括数据的全貌。就像给一个人拍证件照,身高、体重、年龄,几个数字就勾勒出轮廓了。

在电力能耗分析中,我最常用的三个指标是:均值、中位数、标准差

4.1.1 均值(Mean)—— 数据的「重心」

均值就是平均值。把所有能耗值加起来,除以样本数量。它代表数据的「中心位置」。

但我要提醒你:均值很怕「极端值」。我在一个工厂项目里遇到过,某天设备故障,能耗飙到平时的5倍。就这一个点,把整周的均值拉高了20%。你说这均值还能代表「正常水平」吗?不能。

⚠️ 注意: 均值对异常值非常敏感。如果数据中存在明显的离群点,均值可能会「失真」。

4.1.2 中位数(Median)—— 数据的「分水岭」

中位数,就是把数据从小到大排好,取最中间的那个数。如果数据量是偶数,就取中间两个数的平均值。

中位数的好处是:它不怕极端值。还是刚才那个工厂的例子,哪怕有一天能耗爆表,中位数几乎纹丝不动。因为它只关心「位置」,不关心「数值大小」。

所以,我一般会同时看均值和中位数。如果两者接近,说明数据分布比较对称。如果均值远大于中位数,那大概率是右边有「长尾巴」—— 也就是存在一些特别高的能耗值。

4.1.3 标准差(Standard Deviation)—— 数据的「离散度」

标准差衡量的是数据「有多散」。标准差大,说明数据忽高忽低,波动剧烈。标准差小,说明数据比较稳定,都在均值附近晃悠。

在电力能耗里,标准差特别有用。比如,你发现某条生产线的能耗标准差突然变大,那就要警惕了 —— 可能是设备运行不稳定,或者有人在偷偷用电。

嗯,这里要注意:标准差和均值是「配套」使用的。只看均值不看标准差,就像只看成绩不看排名,信息不完整。

4.1.4 实战:用Python算描述性统计

代码很简单,我们用Pandas一行搞定。假设数据已经清洗好,存在DataFrame df 里,能耗列叫 power_kw

import pandas as pd

# 读取数据(假设已清洗)
df = pd.read_csv('factory_power.csv')

# 描述性统计
stats = df['power_kw'].describe()
print(stats)

# 或者单独提取
mean_val = df['power_kw'].mean()
median_val = df['power_kw'].median()
std_val = df['power_kw'].std()

print(f"均值: {mean_val:.2f} kW")
print(f"中位数: {median_val:.2f} kW")
print(f"标准差: {std_val:.2f} kW")

describe() 方法会一次性输出:计数、均值、标准差、最小值、25%分位数、50%分位数(就是中位数)、75%分位数、最大值。非常方便。

💡 我的习惯: 拿到数据后,先跑一遍 describe(),看看有没有明显异常。比如最大值是均值的10倍以上,那基本可以确定有离群点。

4.2 数据分布可视化:用图表「看见」分布

数字虽然精确,但不够直观。我更喜欢先看图,再看数。图能让你一眼看出数据的「形状」—— 是胖是瘦,是偏左还是偏右,有没有「孤岛」。

这里我重点讲两个图:直方图箱线图。这两个是EDA的「黄金搭档」。

4.2.1 直方图(Histogram)—— 数据的「地形图」

直方图把数据分成若干个「桶」(bin),然后统计每个桶里有多少个数据点。横轴是数值范围,纵轴是频数或频率。

看直方图,我主要看三点:

  • 中心位置:数据集中在哪个区间?
  • 分布形状:是正态分布(钟形)?还是偏态分布(一边长尾巴)?
  • 异常区间:有没有孤零零的「小山峰」远离主群体?

我曾经帮一个商场做能耗分析,直方图一画出来,发现凌晨3点到5点居然有个小高峰。一查,原来是保洁阿姨偷偷开了大功率吸尘器。你看,图不会骗人。

import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 画直方图
plt.figure(figsize=(10, 6))
sns.histplot(df['power_kw'], bins=30, kde=True)
plt.title('工厂能耗分布直方图')
plt.xlabel('功率 (kW)')
plt.ylabel('频数')
plt.show()

这里我加了 kde=True,它会画一条核密度估计曲线,相当于把直方图的轮廓「平滑」一下,更容易看出分布形态。

🔑 关键点: bins(桶数)的选择很重要。太少会丢失细节,太多会显得杂乱。一般先试20-30个,再根据情况调整。

4.2.2 箱线图(Box Plot)—— 数据的「体检报告」

箱线图,我称之为「数据的体检报告」。它用五个数字概括分布:最小值、下四分位数(Q1)、中位数、上四分位数(Q3)、最大值。同时,它还会把异常值(离群点)单独标出来。

箱线图怎么看?

  • 箱子:从Q1到Q3,包含了中间50%的数据。箱子越窄,数据越集中。
  • 箱子中间的线:中位数。如果不在箱子正中间,说明数据偏态。
  • 须(whisker):从箱子延伸出去的线,通常到1.5倍IQR(四分位距)的位置。
  • 须之外的点:就是异常值。这些点要特别关注。

我记得有一次,某工厂的能耗箱线图显示,每周五下午都有一个「飞点」超出上须。后来发现,是工人下班前集中启动设备做「收尾工作」。这个规律,光看均值是发现不了的。

# 画箱线图
plt.figure(figsize=(8, 6))
sns.boxplot(y=df['power_kw'])
plt.title('工厂能耗箱线图')
plt.ylabel('功率 (kW)')
plt.show()

如果想对比不同时间段的分布,可以画分组箱线图。比如,对比一周七天的能耗分布:

# 假设有 'weekday' 列,表示星期几
plt.figure(figsize=(12, 6))
sns.boxplot(x='weekday', y='power_kw', data=df)
plt.title('不同工作日的能耗分布对比')
plt.xlabel('星期')
plt.ylabel('功率 (kW)')
plt.show()

这种图一出来,哪个工作日能耗高、哪个波动大,一目了然。

⚠️ 注意: 箱线图对异常值的定义是基于IQR的,但实际业务中,有些「异常值」可能是正常的生产高峰。不要盲目剔除,要结合业务判断。

4.3 描述性统计 + 可视化:组合拳

光看数字,你可能觉得「均值500,标准差80」,没什么感觉。但如果你同时看到直方图是右偏的,箱线图上面有一堆离群点,你就会立刻意识到:这数据有问题,需要深挖

我个人习惯,每次分析都先输出一个「四件套」:

  1. 描述性统计表(均值、中位数、标准差、四分位数)
  2. 直方图(看整体分布形态)
  3. 箱线图(看异常值和离散程度)
  4. 时间序列折线图(看趋势,这个后面章节会讲)

这四样东西摆在一起,数据的基本面就全了。接下来是做假设检验、建模型,还是写报告,心里都有底。

💡 避坑指南: 我曾经犯过一个错 —— 只看均值,没看分布。结果模型预测偏差很大。后来发现数据是双峰的(两个不同的生产模式混在一起),均值根本代表不了任何一边。所以,先看图,再算数,这个顺序别搞反了。

4.4 本章小结

这一章我们讲了EDA的两个核心工具:

  • 描述性统计:用均值、中位数、标准差快速量化数据特征。记住,均值怕极端值,中位数更稳健。
  • 数据分布可视化:直方图看整体形状,箱线图看异常值和离散度。两者结合,数据无处遁形。

下一章,我们会进入更高级的探索 —— 相关性分析和特征工程。到时候,这些基础分析的结果会派上大用场。

好,今天的课就到这里。记得动手跑一下代码,把你们自己的数据画出来看看。有什么问题,我们群里聊。


公众号:蓝海资料掘金营,微信deep3321