3. 数据读取与概览:用pandas打开风电数据的第一道门
做风电数据分析,第一步永远是把数据请进内存。我见过不少新手,拿到几十兆的CSV文件就直接双击打开Excel,结果卡死半天。其实用pandas读取,几行代码就搞定。今天我们就聊聊怎么把数据读进来,然后快速摸清它的底细。
3.1 读取CSV文件:最常用的操作
风场的数据,十有八九是CSV格式。SCADA系统每天生成一堆日志,运维记录也常导出为CSV。我习惯用pd.read_csv(),它就像一把万能钥匙。
import pandas as pd
# 读取风电机组运行数据
df = pd.read_csv('wind_turbine_data.csv')
print('数据加载完成')
嗯,这里要注意。实际项目中,CSV文件经常带点小毛病。比如时间列被识别成字符串,或者某些列里有空值。我建议你加上几个常用参数:
df = pd.read_csv(
'wind_turbine_data.csv',
parse_dates=['timestamp'], # 自动解析时间列
encoding='utf-8', # 避免中文乱码
low_memory=False # 防止混合类型警告
)
chunksize 参数。我曾经处理一个3GB的SCADA日志,分块读取后内存占用从90%降到了30%。
3.2 读取Excel文件:处理运维报表
Excel文件在风场也很常见。运维日报、月度分析报告,很多老师傅习惯用Excel。pandas读取Excel需要额外装一个库,但用起来不复杂。
# 读取Excel文件
df_excel = pd.read_excel('monthly_report.xlsx', sheet_name='运行数据')
你想想看,一个Excel文件里可能有好几个sheet。有的放SCADA数据,有的放停机记录。用sheet_name参数指定你要读哪个,省得搞混。
openpyxl 或 xlrd 库。我遇到过有人没装依赖,代码跑一半报错,挺尴尬的。
3.3 查看数据维度与列名
数据读进来了,第一件事是什么?我个人习惯先看形状和列名。就像拿到一个新工具,先看看它长什么样。
# 查看数据维度(行数, 列数)
print('数据维度:', df.shape)
# 查看所有列名
print('列名列表:')
print(df.columns.tolist())
输出大概是这样:
数据维度: (8760, 15)
列名列表:
['timestamp', 'wind_speed', 'power_output', 'rotor_speed',
'blade_pitch', 'generator_temp', 'ambient_temp', 'status_code']
8760行,正好是一年8760个小时的数据。15列,包含了风速、功率、转速这些关键参数。看到这个,我心里就有数了。
3.4 info()方法:快速诊断数据类型
info() 是我最常用的方法之一。它就像给数据做个体检,告诉你每列的类型、非空数量、内存占用。
df.info()
输出示例:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8760 entries, 0 to 8759
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 timestamp 8760 non-null datetime64[ns]
1 wind_speed 8745 non-null float64
2 power_output 8760 non-null float64
3 rotor_speed 8730 non-null float64
4 blade_pitch 8760 non-null float64
5 generator_temp 8710 non-null float64
6 ambient_temp 8760 non-null float64
7 status_code 8760 non-null int64
dtypes: datetime64[ns](1), float64(6), int64(1)
Memory usage: 1.1 MB
看到没?wind_speed 只有8745个非空值,说明有15个缺失。 generator_temp 更少,只有8710个。这些缺失值,可能就是传感器故障或者通讯中断导致的。我曾经在某个风场排查过,发现发电机温度传感器在高温时段经常掉线,后来换了批传感器才解决。
Non-Null Count 和 Dtype。如果时间列显示为 object 而不是 datetime64,说明没解析成功,后面做时间序列分析会出问题。
3.5 describe()方法:统计概览一把抓
describe() 能快速给出数值列的统计信息。均值、标准差、四分位数,一目了然。
df.describe()
输出表格:
| 指标 | wind_speed | power_output | rotor_speed | generator_temp |
|---|---|---|---|---|
| count | 8745.00 | 8760.00 | 8730.00 | 8710.00 |
| mean | 8.52 | 1520.34 | 12.18 | 45.67 |
| std | 4.21 | 890.56 | 3.45 | 12.34 |
| min | 0.00 | 0.00 | 0.00 | 15.20 |
| 25% | 5.10 | 780.00 | 9.80 | 36.50 |
| 50% | 8.30 | 1450.00 | 12.00 | 44.80 |
| 75% | 11.70 | 2200.00 | 14.50 | 54.30 |
| max | 25.40 | 3000.00 | 18.20 | 78.90 |
看到这个表,我一般会快速扫几眼:
- 均值 vs 中位数: 如果两者差距大,说明数据有偏态。比如风速均值8.52,中位数8.30,还算正常。
- 最小值: 风速最小0.0,功率也是0.0,这可能是停机时段。但发电机温度最小15.2度,说明没低于环境温度太多,合理。
- 最大值: 发电机温度78.9度,接近报警阈值了。我遇到过一台机组,夏天发电机温度经常冲到80度以上,后来发现散热风扇坏了。
3.6 数据类型检查:别让类型坑了你
数据类型不对,后面所有计算都是错的。我见过有人把风速列当成字符串,结果求均值时报错。用 dtypes 属性可以快速检查:
# 查看每列的数据类型
print(df.dtypes)
输出:
timestamp datetime64[ns]
wind_speed float64
power_output float64
rotor_speed float64
blade_pitch float64
generator_temp float64
ambient_temp float64
status_code int64
dtype: object
如果发现某列类型不对,可以用 astype() 转换:
# 强制转换类型
df['status_code'] = df['status_code'].astype('int64')
df['wind_speed'] = pd.to_numeric(df['wind_speed'], errors='coerce')
pd.to_numeric(..., errors='coerce') 可以把非法值转为NaN,然后再处理缺失值。
3.7 本章知识体系
下面这张图,帮你理清数据读取与概览的核心流程:
说白了,数据读取与概览就是给数据做一次全面体检。读进来、看形状、查类型、看统计,每一步都不能省。我做了这么多年风电数据分析,发现80%的问题都出在数据读取阶段。类型不对、缺失值没发现、时间没解析,后面分析再花哨也是白搭。
好了,这一章就到这里。记住,拿到数据别急着分析,先花5分钟做概览。这5分钟,能帮你省下后面5小时的排查时间。