3. 数据探索性分析(EDA):先看看你的数据长什么样

拿到风机主轴承温度数据之后,我个人的习惯是——先别急着建模。你想想看,数据就像一块原材料,你不先摸摸它的脾气,直接扔进模型里,十有八九要翻车。EDA 这一步,说白了就是跟数据打个照面,看看它干不干净、有没有坑、趋势对不对。

这一章,咱们就一起动手,把数据质量、缺失值、异常值、温度分布和趋势,挨个捋一遍。

3.1 数据质量概览:先扫一眼全局

我一般会用 df.info()df.describe() 快速扫一眼。这两个方法,一个告诉你字段类型和缺失情况,一个告诉你数值分布的基本统计量。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 读取数据
df = pd.read_csv('bearing_temp.csv', parse_dates=['timestamp'])
df.set_index('timestamp', inplace=True)

# 数据概览
print(df.info())
print(df.describe())

输出结果里,我最关注三件事:

  • 字段类型对不对——时间戳是不是 datetime 类型?数值列是不是 float?
  • 非空数量——如果某个字段空值太多,那后面就得小心处理了。
  • 数值范围——比如温度最小值 10°C,最大值 120°C,这合理吗?
小提示: 我在项目里遇到过,某台风机的温度传感器坏了,连续三天输出恒定的 25°C。这种数据在 info() 里看不出问题,但 describe() 里标准差为 0 就会暴露。所以,标准差为 0 的字段,一定要警惕。

3.2 缺失值与异常值初步检测

缺失值处理,说白了就两步:先找出来,再决定怎么补。

3.2.1 缺失值检测

# 缺失值统计
missing = df.isnull().sum()
missing_ratio = missing / len(df)
print(pd.DataFrame({'缺失数': missing, '缺失比例': missing_ratio}))

如果缺失比例小于 5%,我一般直接填充均值或中位数。如果超过 20%,那就要考虑这个特征是不是还能用了。我曾经处理过一台风机,风速传感器缺失率达到 40%,最后只能放弃这个特征,改用其他相关变量替代。

3.2.2 异常值初步检测

异常值检测,我习惯先用 IQR(四分位距)法快速筛一遍。

def detect_outliers_iqr(data, column):
    Q1 = data[column].quantile(0.25)
    Q3 = data[column].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    outliers = data[(data[column] < lower_bound) | (data[column] > upper_bound)]
    return outliers

outliers_temp = detect_outliers_iqr(df, 'bearing_temp')
print(f'主轴承温度异常值数量:{len(outliers_temp)}')
注意: IQR 方法对正态分布的数据效果较好,但风机温度数据往往有偏态。我曾经遇到过,夏季高温时段的数据被 IQR 误判为异常值,实际上那是正常工况。所以,初步检测后一定要结合业务知识人工复核。

3.3 温度分布与趋势可视化

可视化是 EDA 里最直观的一步。我一般会画三张图:分布图、时序趋势图、箱线图。

3.3.1 温度分布直方图

plt.figure(figsize=(10, 5))
sns.histplot(df['bearing_temp'], bins=50, kde=True, color='steelblue')
plt.title('主轴承温度分布')
plt.xlabel('温度 (°C)')
plt.ylabel('频次')
plt.grid(True, alpha=0.3)
plt.show()

这张图能告诉你:温度主要集中在哪个区间?是不是双峰分布?如果出现双峰,那很可能对应两种不同的工况(比如低负荷和高负荷)。

3.3.2 时序趋势图

plt.figure(figsize=(14, 5))
plt.plot(df.index, df['bearing_temp'], linewidth=0.5, color='darkorange')
plt.title('主轴承温度时序趋势')
plt.xlabel('时间')
plt.ylabel('温度 (°C)')
plt.grid(True, alpha=0.3)
plt.show()

趋势图能看出季节性、周期性,以及有没有突然的尖峰。我记得有一次,趋势图上出现了一个持续 2 小时的温度陡升,后来排查发现是润滑系统故障。这种模式,光靠统计指标是抓不到的。

3.3.3 箱线图看异常

plt.figure(figsize=(8, 4))
sns.boxplot(x=df['bearing_temp'], color='lightcoral')
plt.title('主轴承温度箱线图')
plt.xlabel('温度 (°C)')
plt.show()

箱线图能直观显示中位数、四分位距和异常点。如果异常点特别多,那就要考虑是不是数据采集本身有问题。

3.4 知识体系总览

下面这张图,是我自己总结的 EDA 核心逻辑。你可以把它当作一个检查清单,每次做 EDA 时对照着来。

EDA 数据探索性分析核心流程 数据概览 info() / describe() 缺失值检测 isnull() / 填充策略 异常值检测 IQR / 业务复核 分布可视化 直方图 + KDE 趋势可视化 时序折线图 异常可视化 箱线图 输出:数据质量报告 + 可视化看板

3.5 实战小结

这一章的内容,说白了就是三件事:

  • 数据概览——用 info() 和 describe() 快速摸清数据底细。
  • 缺失值与异常值——用 isnull() 和 IQR 法初步筛查,但一定要结合业务知识复核。
  • 可视化——分布图、趋势图、箱线图,三张图基本能覆盖大部分信息。

嗯,这里要注意一点:EDA 不是一次性工作。你在后续建模过程中,如果发现模型效果不好,很可能要回头重新做 EDA,看看是不是漏掉了什么模式。我自己的经验是,EDA 做得越细,后面踩的坑就越少。

核心要点: 数据质量决定了模型的天花板。EDA 花的时间,后面建模会加倍还给你。

专注资料整理