复现已有算法

This commit is contained in:
cloud
2026-07-14 15:43:18 +08:00
parent abebd2a683
commit 50b8111fd9
860 changed files with 182250 additions and 18 deletions
@@ -0,0 +1,353 @@
# 风机历史数据无效值清洗与功率计算设计
## 背景与目标
当前 `docs/完整年数据/` 目录下保存了 16 台风机从 `2024-09-01 14:00:00``2025-09-01 14:00:00` 的历史数据。以 `01_2024-09-01_14-00-00-2025-09-01_14-00-00_风机历史数据.xls` 为例,文件为 10 分钟粒度历史数据,包含风速、发电机转速、桨叶角度和有功功率等字段。
本文档定义两类计算口径:
- 无效值清洗:从历史数据中剔除停机、无风、无功率、异常转速、异常风速、疑似限功率和统计离群点。
- 风机功率计算:直接使用实测 `有功功率(kW)` 作为时刻功率,并基于清洗后的数据计算风速-功率曲线和发电量。
## 数据输入
当前历史数据字段如下:
| 字段 | 单位 | 用途 |
| --- | --- | --- |
| 时间 | - | 数据时间戳,当前主要为 10 分钟间隔 |
| 风机编号 | - | 区分风机,如 `01#` |
| 风机限功率时间(s) | s | 累计类字段,不能直接用 `> 0` 判断当前是否限功率 |
| 变流器发电机转速(rpm) | rpm | 辅助判断运行状态和转速异常 |
| 发电机转速(rpm) | rpm | 判断是否发电、计算叶尖速比时使用 |
| 风速(m/s) | m/s | 风速分箱和功率曲线计算 |
| 当前桨叶角度(°) | ° | 辅助识别停机、顺桨、限功率或异常状态 |
| 有功功率(kW) | kW | 实测输出功率,作为风机时刻功率 |
## 设计原则
- 先清洗后计算,所有功率曲线、发电量、性能指标均基于清洗后的有效数据。
- 实测功率优先,已有 `有功功率(kW)` 时不使用理论风功率公式反推时刻功率。
- 清洗规则分层执行,基础无效值直接剔除,疑似限功率和统计离群点应可追溯标记。
- 每个风速区间必须输出样本数,样本不足的区间不能作为正式功率曲线点。
- 额定功率、额定风速、叶轮直径、齿轮箱速比等机型参数必须配置化,不能写死为旧脚本中的 `4800``6700`
## 无效值清洗方案
### 1. 字段校验
读取每个 `.xls` 文件后,先检查必需字段:
```text
时间
风机编号
发电机转速(rpm)
风速(m/s)
当前桨叶角度(°)
有功功率(kW)
```
如果缺少 `有功功率(kW)``风速(m/s)`,该文件不能用于功率曲线计算。如果缺少 `发电机转速(rpm)``当前桨叶角度(°)`,仍可做基础风速-功率统计,但不能执行完整运行状态清洗。
### 2. 时间清洗
时间字段需转换为标准时间戳。以下数据应剔除或单独标记:
- 时间为空或无法解析。
- 同一风机同一时间重复记录。
- 时间倒序记录。
- 与前一条记录间隔明显异常的数据段。
当前数据主要为 10 分钟粒度。若用于发电量积分,建议对异常间隔单独处理,不要默认每条都是 10 分钟。
### 3. 基础有效发电点过滤
用于计算风速-功率曲线时,建议保留满足以下条件的数据:
```text
风速(m/s) > 0
有功功率(kW) > 0
发电机转速(rpm) > 1
```
说明:
- `有功功率(kW) = 0` 通常表示未发电、停机、待机或数据无效,不应参与功率曲线均值。
- `发电机转速(rpm) <= 1` 通常表示机组未处于正常发电转动状态。
- 风速为 0 或负数不符合功率曲线计算输入条件。
### 4. 物理边界过滤
按机型参数增加边界过滤:
| 指标 | 建议规则 | 说明 |
| --- | --- | --- |
| 风速 | `0 < 风速 <= 35` | 超出范围优先视为传感器或导出异常 |
| 有功功率 | `0 < 有功功率 <= 额定功率 * 1.10` | 保留少量超额定裕度,过高视为异常 |
| 发电机转速 | `0 < 转速 <= 最大允许转速 * 1.05` | 最大允许转速从机型配置获取 |
| 桨叶角度 | `-10 <= 桨叶角度 <= 95` | 极端负角度或过大角度需结合状态判断 |
当前 01 号文件最大有功功率约为 `3307 kW`,因此该机组额定功率应按约 `3300 kW` 级配置,不能使用旧脚本中的 `4800 kW``6700 kW`
### 5. 疑似限功率识别
`风机限功率时间(s)` 是累计时间类字段,当前文件中全量数据均大于 0,不能用 `风机限功率时间(s) > 0` 判断当前记录是否限功率。
建议使用相邻记录增量辅助判断:
```text
限功率时间增量 = 当前行 风机限功率时间(s) - 上一行 风机限功率时间(s)
```
疑似限功率点可按以下条件组合识别:
- 限功率时间增量大于 0。
- 风速较高,但有功功率长期低于同风速段正常中位功率。
- 相邻多个 10 分钟点功率接近同一平台值,但风速变化明显。
- 桨叶角度明显偏大,且功率未随风速增加。
建议先把疑似限功率数据标记为 `is_limited = true`,不要直接删除。计算正常功率曲线时排除;分析限功率损失时保留。
### 6. 叶尖速比异常过滤
如果需要使用叶尖速比辅助清洗,应采用标准公式,不建议沿用旧脚本中的硬编码乘法。
叶尖速比计算公式:
```text
叶轮转速(rpm) = 发电机转速(rpm) / 齿轮箱速比
叶尖速比 = 叶轮转速(rpm) * 2π / 60 * 叶轮半径(m) / 风速(m/s)
```
示例:
```text
lambda = generator_rpm / gearbox_ratio * 2π / 60 * rotor_radius / wind_speed
```
叶轮半径、齿轮箱速比必须来自机型配置。清洗时可按风速分箱,对每个风速区间内的叶尖速比使用 IQR 或 MAD 剔除离群点。
### 7. 风速-功率离群点过滤
按风速分箱后,对每个风速区间内的 `有功功率(kW)` 做统计过滤。
推荐分箱宽度:
```text
0.5 m/s
```
样本数规则:
| 区间样本数 | 处理方式 |
| --- | --- |
| `< 10` | 不剔除,但标记为样本不足,不参与正式曲线 |
| `10 - 29` | 可做宽松离群过滤,结果标记为低置信度 |
| `>= 30` | 执行正式离群过滤,可用于功率曲线 |
IQR 过滤规则:
```text
Q1 = 区间功率 25% 分位数
Q3 = 区间功率 75% 分位数
IQR = Q3 - Q1
下限 = Q1 - 1.5 * IQR
上限 = Q3 + 1.5 * IQR
保留 下限 <= 有功功率 <= 上限 的数据
```
高风速额定平台区建议额外处理。额定风速以上,功率应接近额定功率;如果出现大量高风速低功率点,应优先判断为限功率、停机、故障或弃风,不应简单参与正常功率曲线均值。
## 风机功率计算方案
### 1. 时刻功率
历史数据中已有实测功率字段,时刻功率直接取:
```text
风机时刻功率(kW) = 有功功率(kW)
```
不建议使用以下理论公式替代实测时刻功率:
```text
P = 0.5 * ρ * A * Cp * v^3
```
该公式适合估算风能理论功率或做性能分析,需要空气密度、叶轮扫掠面积和功率系数,不适合在已有实测有功功率时反算实际输出。
### 2. 风速-功率曲线
风速-功率曲线用于描述不同风速下机组的实测输出能力。计算步骤:
```text
1. 使用清洗后的有效发电点。
2. 按风速分箱,建议 0.5 m/s 一个区间。
3. 每个区间统计有功功率。
4. 输出平均功率、中位数功率、样本数、标准差和分位数。
5. 样本不足或疑似限功率区间只标记,不作为正式曲线点。
```
区间定义建议采用左开右闭:
```text
(区间起点, 区间终点]
```
例如:
```text
(3.75, 4.25] -> 风速中心 4.0 m/s
(4.25, 4.75] -> 风速中心 4.5 m/s
```
输出字段:
| 字段 | 说明 |
| --- | --- |
| 风机编号 | 当前风机 |
| 风速区间起点 | 左边界 |
| 风速区间终点 | 右边界 |
| 风速中心 | 区间中点 |
| 样本数 | 清洗后有效点数量 |
| 平均功率(kW) | 区间功率均值 |
| 中位数功率(kW) | 区间功率中位数 |
| 功率标准差(kW) | 区间功率离散程度 |
| P25功率(kW) | 25% 分位数 |
| P75功率(kW) | 75% 分位数 |
| 置信度 | 正常、低样本、样本不足、疑似限功率 |
### 3. 发电量计算
若需要计算年发电量,应对功率按时间积分。
若确认每条数据为 10 分钟间隔:
```text
单条发电量(kWh) = 有功功率(kW) * 10 / 60
总发电量(kWh) = 所有单条发电量求和
```
更稳妥的通用算法是使用相邻时间戳差值:
```text
时间间隔(h) = 下一条时间 - 当前时间
单条发电量(kWh) = 当前有功功率(kW) * 时间间隔(h)
```
时间间隔异常时建议标记,不直接参与年发电量统计,或按业务规则补齐。
### 4. 理论风功率和性能指标
如需评估风能利用效率,可额外计算理论风功率:
```text
扫掠面积 A = π * 叶轮半径^2
理论风功率(kW) = 0.5 * 空气密度 * A * 风速^3 / 1000
功率系数 Cp = 有功功率(kW) / 理论风功率(kW)
```
注意:
- 空气密度应使用温度、气压、湿度或场站海拔修正。
- Cp 只用于性能分析,不用于替代实测 `有功功率(kW)`
- Cp 超出合理范围时,应优先检查风速测量、空气密度、功率单位和数据清洗规则。
## 数据处理流程
```text
读取 XLS 文件
-> 字段校验
-> 时间解析与排序
-> 基础有效发电点过滤
-> 物理边界过滤
-> 标记疑似限功率
-> 可选:叶尖速比异常过滤
-> 风速-功率分箱离群过滤
-> 输出清洗后明细
-> 输出风速-功率曲线表
-> 输出功率曲线图
-> 可选:计算发电量和性能指标
```
## 参数配置建议
| 参数 | 建议默认值 | 说明 |
| --- | --- | --- |
| 风速分箱宽度 | `0.5 m/s` | 功率曲线统计常用粒度 |
| 最小正式样本数 | `30` | 低于该值标记低置信度 |
| 最小保留样本数 | `10` | 低于该值不参与正式曲线 |
| IQR 系数 | `1.5` | 常规离群点过滤 |
| 发电机最小转速 | `1 rpm` | 判断是否发电 |
| 功率上限 | `额定功率 * 1.10` | 防止异常高功率 |
| 风速上限 | `35 m/s` | 防止异常风速 |
机型配置建议包含:
```text
风机编号
额定功率(kW)
额定风速(m/s)
叶轮直径(m)
齿轮箱速比
最大允许发电机转速(rpm)
切入风速(m/s)
切出风速(m/s)
```
## 验证计划
### 脚本验证
- 读取 01 号风机文件,确认字段数量和字段名正确。
- 统计原始行数、有效发电点数量、剔除数量和剔除原因。
- 输出每个风速区间的样本数、平均功率和中位数功率。
- 检查空文件、缺字段文件、全无有效数据文件不会报错。
### 结果验证
- 功率曲线应随风速整体上升,并在额定风速附近进入平台。
- 01 号风机最大实测功率约 `3307 kW`,额定功率配置应与该量级一致。
- 高风速低功率点应被标记为疑似限功率、停机或异常,而不是直接拉低正式曲线。
- 样本数不足的风速区间应在结果中明确标记。
### 人工复核
- 抽查被剔除的数据,确认不是正常发电点被误删。
- 抽查疑似限功率点,结合桨叶角度和限功率时间增量确认规则有效。
- 对比厂家功率曲线或历史报告,确认实测曲线形态合理。
## 风险与对策
| 风险 | 影响 | 对策 |
| --- | --- | --- |
| 额定功率配置错误 | 功率上限过滤和平台判断失真 | 按每台机组实测最大功率和机型资料确认 |
| 把累计限功率时间误当状态量 | 大量正常数据被误删 | 使用相邻增量和功率形态综合判断 |
| 分箱样本数过少 | 曲线点随机波动大 | 输出样本数和置信度,低样本不参与正式曲线 |
| 叶尖速比公式错误 | 清洗结果偏差 | 使用标准公式,并配置叶轮半径和齿轮箱速比 |
| 时间间隔异常 | 发电量计算偏差 | 使用相邻时间差,并对异常间隔标记 |
## 后续实施建议
建议将现有两个脚本整理为一个可配置处理流程:
```text
clean_wind_history.py
- 读取单台或多台风机历史数据
- 输出清洗后明细
- 输出风速-功率曲线统计表
- 输出功率曲线图
- 输出清洗摘要报告
```
同时保留每条数据的清洗标记字段,例如:
```text
is_valid_generation
is_out_of_physical_range
is_suspected_limited
is_power_outlier
invalid_reason
```
这样后续既能生成正式曲线,也能追溯每条数据为什么被保留或剔除。