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)