4. 数据加载与初步探索:用Pandas看清你的数据
各位工程师朋友,欢迎来到实战环节。
前面我们聊了风机故障诊断的整体思路,也搭建好了分析环境。但说实话,真正动手的第一步,往往是最容易出问题的。我见过不少项目,模型跑得飞起,结果回头一看——数据加载阶段就埋了雷。
今天我们就来聊聊,怎么用Pandas把数据请进来,并且快速摸清它的底细。
4.1 数据加载:把文件变成DataFrame
我个人习惯,拿到数据的第一件事,不是急着分析,而是先看一眼文件长什么样。风机数据通常以CSV格式存储,比如这样:
import pandas as pd
# 加载风机振动数据
df = pd.read_csv('fan_vibration_data.csv')
print('数据加载完成,共 {} 行 {} 列'.format(df.shape[0], df.shape[1]))
嗯,这里要注意。read_csv()有很多参数,我建议你养成两个好习惯:
- 指定编码:中文数据经常遇到编码问题,加个
encoding='utf-8'或'gbk' - 检查分隔符:有些文件用制表符或分号,记得设置
sep='\t'或sep=';'
4.2 快速浏览:head()和tail()
数据加载进来了,别急着往下走。先看看数据长什么样。
# 查看前5行
print(df.head())
# 查看后5行
print(df.tail())
head()默认显示前5行,你可以传参,比如head(10)。我一般先看5行,如果感觉数据怪怪的,再看10行。
你想想看,如果数据加载错了,或者列名对不上,这一步就能发现。我曾经遇到过,客户说数据有100个传感器通道,结果head()一看,只有99列——少了一列数据,后面所有分析都得重来。
4.3 数据概览:info()告诉你一切
info()是我最常用的函数之一。它就像数据的体检报告,一行一行告诉你:
df.info()
输出大概长这样:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 timestamp 10000 non-null object
1 vibration_x 10000 non-null float64
2 vibration_y 9998 non-null float64
3 vibration_z 10000 non-null float64
4 temperature 10000 non-null float64
5 rpm 10000 non-null int64
6 current 9995 non-null float64
7 voltage 10000 non-null float64
8 power 10000 non-null float64
9 wind_speed 10000 non-null float64
10 fault_label 10000 non-null int64
11 sensor_id 10000 non-null object
dtypes: float64(8), int64(2), object(2)
memory usage: 937.5 KB
这里信息量很大,我带你拆解一下:
- 行数:10000条记录,样本量还不错
- 列数:12列,包含时间戳、振动、温度、电流等
- 非空计数:注意看,vibration_y只有9998个非空,current只有9995个——有缺失值!
- 数据类型:float64是数值型,int64是整数型,object一般是字符串或时间戳
4.4 统计描述:describe()的妙用
info()告诉你数据有没有缺失,describe()则告诉你数据长什么样——均值、标准差、最小值、最大值等等。
df.describe()
输出示例:
| vibration_x | vibration_y | vibration_z | temperature | rpm | current | |
|---|---|---|---|---|---|---|
| count | 10000.0 | 9998.0 | 10000.0 | 10000.0 | 10000.0 | 9995.0 |
| mean | 2.34 | 1.89 | 3.12 | 45.6 | 1500.0 | 12.5 |
| std | 0.87 | 0.92 | 1.23 | 5.2 | 120.0 | 3.1 |
| min | 0.12 | 0.08 | 0.15 | 28.0 | 800.0 | 2.1 |
| 25% | 1.56 | 1.23 | 2.01 | 41.0 | 1400.0 | 10.2 |
| 50% | 2.30 | 1.85 | 3.08 | 45.0 | 1500.0 | 12.3 |
| 75% | 3.10 | 2.50 | 4.15 | 50.0 | 1600.0 | 14.8 |
| max | 8.90 | 7.60 | 9.80 | 68.0 | 1800.0 | 25.0 |
看这个表,你能发现什么?
- 振动值:vibration_x的均值2.34,最大值8.9——这个最大值明显偏高,可能是故障状态
- 温度:最高68度,正常风机运行温度一般在40-55度,68度有点高了
- 转速:800-1800 RPM,范围合理,但800转是不是停机状态?
说白了,describe()就是帮你快速建立对数据的直觉。我每次拿到新数据,都会先跑一遍describe(),然后心里就有数了。
4.5 缺失值检查:别让NaN坑了你
刚才info()里我们看到有缺失值。现在来精确检查一下:
# 检查每列缺失值数量
print(df.isnull().sum())
# 缺失值占比
print(df.isnull().sum() / len(df) * 100)
输出:
timestamp 0
vibration_x 0
vibration_y 2
vibration_z 0
temperature 0
rpm 0
current 5
voltage 0
power 0
wind_speed 0
fault_label 0
sensor_id 0
dtype: int64
vibration_y缺失2条,current缺失5条。占比很小,不到0.1%。
我曾经遇到过一个项目,电流数据缺失了30%。一开始以为是采集故障,后来发现是某个传感器在特定工况下会掉线。如果不分析原因直接填充,模型就会学到错误规律。
4.6 数据类型检查:别让类型坑了你
数据类型不对,后面所有计算都会出问题。我建议你养成这个习惯:
# 查看每列数据类型
print(df.dtypes)
# 单独检查某列
print(df['timestamp'].dtype)
常见问题:
- 时间戳是object:需要转换成datetime类型,方便后续按时间分析
- 数值列是object:可能混入了字符串,比如'12.5a'这种脏数据
- 整数列是float:可能因为有缺失值,Pandas自动转成了float
转换方法:
# 时间戳转换
df['timestamp'] = pd.to_datetime(df['timestamp'])
# 数值列转换(遇到错误就变成NaN)
df['current'] = pd.to_numeric(df['current'], errors='coerce')
4.7 本章知识体系
下面这张图,帮你理清数据加载与初步探索的完整流程:
4.8 实战小贴士
最后,分享几个我常用的检查套路:
# 一键检查套路
def quick_check(df):
print("="*50)
print("数据形状:", df.shape)
print("="*50)
print("列名:\n", df.columns.tolist())
print("="*50)
print("数据类型:\n", df.dtypes)
print("="*50)
print("缺失值:\n", df.isnull().sum())
print("="*50)
print("统计描述:\n", df.describe())
print("="*50)
print("重复行数:", df.duplicated().sum())
quick_check(df)
这个函数我用了好几年,每次拿到新数据,先跑一遍,心里就有底了。
好了,数据加载和初步探索就聊到这里。记住一句话:数据质量决定了分析质量。这一步花的时间,后面都会加倍还给你。
公众号:蓝海资料掘金营,微信deep3321