Files
wind_power_cal/docs/清洗完后直接生成功率曲线.py
T
2026-07-14 09:10:06 +08:00

149 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
# ----------------------
# 配置参数
# ----------------------
RAW_DATA_PATH = Path(r'H:\尽调项目\和展清云洛阳项目\6#\6 处理后.xlsx')
RESULT_TABLE_PATH = Path(r'H:\尽调项目\和展清云洛阳项目\6#\6风速区间功率均值表.xlsx')
RESULT_PLOT_PATH = Path(r'H:\尽调项目\和展清云洛阳项目\6#\6风速功率曲线.png')
RATED_POWER = 6700 # 额定功率
RATED_WIND_SPEED = 18 # 额定风速
POWER_STEP = 5
WIND_SPEED_STEP = 0.5 # 风速区间步长
WIND_SPEED_CHANGE_THRESHOLD = 1
#TIME_THRESHOLD = pd.Timedelta(hours=2)
IQR_MULTIPLIER = 1.5
MIN_DATA_COUNT = 3
def load_data(file_path):
try:
if not file_path.exists():
raise FileNotFoundError(f"文件不存在: {file_path}")
data = pd.read_excel(file_path, engine='openpyxl')
print(f"成功读取数据,共{len(data)}条记录")
return data
except Exception as e:
print(f"数据读取错误: {str(e)}")
return None
def clean_scada_data(raw_data):
if raw_data is None or raw_data.empty:
print("无数据可清洗")
return None
data = raw_data.copy()
# ----------------------
# 区间功率均值计算与可视化(核心修改部分)
# ----------------------
def calculate_interval_power_mean(raw_data, wind_speed_step=0.5):
"""按风速区间计算功率平均值,区间采用左开右闭形式 (start, end]"""
if raw_data is None or raw_data.empty:
print("无清洗后的数据可计算均值")
return None
# 确定风速区间范围
wind_min = 1 - wind_speed_step*0.5
wind_max = 25 + wind_speed_step*0.5
# 生成区间起点
wind_intervals = np.arange(wind_min, wind_max, wind_speed_step)
# 计算每个区间的平均功率(核心修改:使用左开右闭区间 (start, end]
result = []
for interval_start in wind_intervals:
interval_end = interval_start + wind_speed_step
# 关键修改:左边界>,右边界≤
mask = (raw_data['平均风速'] > interval_start) & (raw_data['平均风速'] <= interval_end)
interval_data = raw_data[mask]
if not interval_data.empty:
wind_mid = (interval_start + interval_end) / 2 # 区间中点
power_mean = interval_data['平均有功功率'].mean()
result.append({
'风速区间起点': interval_start,
'风速区间终点': interval_end,
'风速': wind_mid,
'实际功率': power_mean,
'区间数据量': len(interval_data),
})
# 转换为DataFrame并按风速排序
result_df = pd.DataFrame(result).sort_values('风速').reset_index(drop=True)
print(f"已计算{len(result_df)}个风速区间的功率平均值(左开右闭区间)")
return result_df
def plot_power_curve(result_df, rated_power, rated_wind_speed, save_path):
"""绘制风速-功率曲线并保存图片"""
if result_df is None or result_df.empty:
print("无数据可绘制曲线")
return False
plt.style.use('seaborn-v0_8-talk')
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制功率曲线
ax.plot(result_df['风速'], result_df['实际功率'],
color='#2c7fb8', linewidth=2.5, marker='o', markersize=5,
label='实际功率曲线')
# 绘制额定功率参考线
ax.axhline(y=rated_power, color='#e41a1c', linestyle='--', linewidth=1.5,
label=f'额定功率 ({rated_power}kW)')
# 绘制额定风速参考线
ax.axvline(x=rated_wind_speed, color='#4daf4a', linestyle='-.', linewidth=1.5,
label=f'额定风速 ({rated_wind_speed}m/s)')
# 设置坐标轴标签和标题
ax.set_xlabel('风速 (m/s)', fontsize=12)
ax.set_ylabel('功率 (kW)', fontsize=12)
ax.set_title('风速-功率曲线(左开右闭区间平均值)', fontsize=14, pad=20)
# 添加网格和图例
ax.grid(alpha=0.3)
ax.legend(fontsize=10)
# 调整布局并保存
plt.tight_layout()
plt.savefig(save_path, dpi=300, bbox_inches='tight')
plt.close()
print(f"功率曲线已保存至 {save_path}")
return True
# ----------------------
# 主程序执行
# ----------------------
if __name__ == "__main__":
# 1. 读取并清洗数据
raw_data = load_data(RAW_DATA_PATH)
# 2. 计算风速区间功率平均值(左开右闭区间)
interval_power_df = calculate_interval_power_mean(raw_data, wind_speed_step=WIND_SPEED_STEP)
# 3. 保存结果表格
if interval_power_df is not None:
try:
RESULT_TABLE_PATH.parent.mkdir(parents=True, exist_ok=True)
interval_power_df.to_excel(RESULT_TABLE_PATH, index=False)
print(f"风速区间功率均值表已保存至 {RESULT_TABLE_PATH}")
except Exception as e:
print(f"保存表格失败:{str(e)}")
# 4. 绘制并保存功率曲线图片
if interval_power_df is not None:
plot_power_curve(interval_power_df, RATED_POWER, RATED_WIND_SPEED, RESULT_PLOT_PATH)