3. 数据读取与初步探索:用pandas打开风电数据的大门

说实话,做风电数据清洗这几年,我见过太多人一上来就急着建模。结果呢?数据读进来全是乱码,或者类型不对,后面全白干。今天咱们就从最基础的开始——怎么把数据安安稳稳地读进来,再摸清它的脾气。

3.1 读取CSV文件:最常用的方式

风电数据最常见的格式就是CSV。为什么?因为SCADA系统、测风塔、CMS系统,导出数据基本都是CSV。我个人习惯用pandas.read_csv(),但有几个参数必须注意。

import pandas as pd

# 基础读取
df = pd.read_csv('wind_turbine_data.csv')

# 实际项目中我常用的方式
df = pd.read_csv(
    'wind_turbine_data.csv',
    encoding='utf-8',          # 避免中文乱码
    parse_dates=['timestamp'],  # 时间列自动解析
    low_memory=False           # 大文件时避免类型推断错误
)
⚠️ 我曾经踩过的坑:有一次读取某风场的SCADA数据,发现时间列全是字符串。后来排查发现,数据里混了"2023/1/1"和"2023-01-01"两种格式。所以我现在都会加上parse_dates参数,让pandas自动处理。

3.2 读取Excel文件:多表单的处理技巧

Excel文件在风电项目中也很常见,尤其是运维记录、故障日志这些。但Excel有个麻烦——一个文件里可能有好几个sheet。

# 读取单个sheet
df = pd.read_excel('fault_log.xlsx', sheet_name='2023年')

# 读取所有sheet
all_sheets = pd.read_excel('fault_log.xlsx', sheet_name=None)
# 返回的是一个字典,key是sheet名

# 指定列类型,避免数值被读成字符串
df = pd.read_excel(
    'wind_data.xlsx',
    dtype={'风速': float, '功率': float}
)
💡 小技巧:如果你发现Excel里的数字读进来变成了"2023/1/1 0:00"这种格式,八成是Excel自动格式化的锅。我一般会在读取时加上dtype=str,然后再手动转换。

3.3 查看数据基本信息:head、info、describe

数据读进来了,第一件事是什么?别急着分析,先看看它长什么样。我通常三步走:

3.3.1 head()——瞄一眼数据长啥样

# 查看前5行
df.head()

# 查看前10行
df.head(10)

# 查看后5行
df.tail()

这一步主要是看:列名对不对?数据有没有明显异常?比如风速列出现负值,那肯定有问题。

3.3.2 info()——摸清数据类型和缺失情况

df.info()

输出结果大概长这样:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8760 entries, 0 to 8759
Data columns (total 8 columns):
 #   Column     Non-Null Count  Dtype         
---  ------     --------------  -----         
 0   timestamp  8760 non-null   datetime64[ns]
 1   风速        8745 non-null   float64       
 2   功率        8730 non-null   float64       
 3   桨距角      8700 non-null   float64       
 4   转速        8750 non-null   float64       
 5   温度        8760 non-null   float64       
 6   风向        8740 non-null   float64       
 7   状态码      8760 non-null   int64         
dtypes: datetime64[ns](1), float64(6), int64(1)
memory usage: 547.6 KB

这里我最关注两点:

  • Non-Null Count:看看哪些列有缺失值。比如上面风速列有15个缺失,功率列有30个缺失。
  • Dtype:数据类型对不对。时间列应该是datetime64,数值列应该是float64或int64。如果发现风速列是object(字符串),那就要小心了。
🔍 实际项目经验:有一次我发现功率列显示的是object类型,一查才发现数据里混了"---"这种占位符。这就是典型的脏数据,后面清洗时得处理掉。

3.3.3 describe()——快速了解数据分布

df.describe()

输出结果:

风速 功率 桨距角 转速 温度 风向
count 8745.0 8730.0 8700.0 8750.0 8760.0 8740.0
mean 7.2 1500.0 5.3 12.1 25.0 180.0
std 4.1 800.0 8.2 3.5 5.0 90.0
min 0.0 -50.0 0.0 0.0 -10.0 0.0
25% 3.5 800.0 0.0 9.0 21.0 90.0
50% 7.0 1500.0 0.0 12.0 25.0 180.0
75% 10.5 2200.0 8.0 15.0 29.0 270.0
max 30.0 2500.0 90.0 20.0 45.0 360.0

这里我一般会快速扫一眼:

  • min和max:有没有明显不合理的数据?比如风速最大30m/s,对于某些机型可能已经切出了,但还在合理范围。但如果出现风速50m/s,那肯定是异常值。
  • count:和总行数对比,看看缺失比例。比如总行数8760,风速只有8745,缺失了15条,占比0.17%,问题不大。
  • mean和std:大致了解数据集中趋势和离散程度。比如功率均值1500kW,标准差800kW,说明波动挺大。
⚠️ 注意:describe()默认只统计数值列。如果你有分类列(比如状态码),可以用df['状态码'].value_counts()来查看分布。

3.4 数据类型概览:为什么类型这么重要?

你想想看,如果风速列是字符串类型,你还能做加减乘除吗?肯定不行。所以数据类型检查是数据清洗的第一步。

# 查看每列的数据类型
df.dtypes

# 单独查看某一列
df['风速'].dtype

# 转换数据类型
df['风速'] = df['风速'].astype(float)
df['timestamp'] = pd.to_datetime(df['timestamp'])

常见的风电数据类型:

数据类型 示例列 pandas类型 说明
时间 timestamp datetime64[ns] 必须转换,否则无法做时间序列分析
连续数值 风速、功率、温度 float64 最常用,注意是否有缺失值
离散数值 状态码、机舱编号 int64 适合做分类统计
分类文本 风机型号、风场名称 object 可以转为category类型节省内存
💡 我的习惯:每次读取数据后,我会先跑一遍df.dtypes,然后手动检查每一列的类型是否合理。如果发现异常,立即处理,绝不拖到后面。

3.5 本章知识体系

下面这张图总结了数据读取与初步探索的核心流程,你可以对照着检查自己的操作步骤:

数据读取与初步探索流程 数据读取 read_csv / read_excel 初步查看 head() / tail() 信息概览 info() 数据类型检查 统计描述 缺失值检查 数据清洗与预处理 核心目标:确保数据类型正确、了解数据分布、发现明显异常

嗯,到这里,数据读取和初步探索就讲完了。说白了,这一步就是给数据做个"体检"——看看它有没有"发烧"(异常值),有没有"缺胳膊少腿"(缺失值),有没有"穿错衣服"(类型错误)。

我个人觉得,这一步花的时间再多都不为过。因为后面所有的分析、建模、可视化,都建立在这个基础上。基础打好了,后面才能走得稳。

📌 核心要点回顾:
  • 读取数据时注意编码、时间解析、类型指定
  • head()看数据长什么样,info()看类型和缺失,describe()看分布
  • 数据类型检查是数据清洗的第一步,发现问题立即处理
专注资料整理