import os import pandas as pd import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import plotly.graph_objects as go from plotly.subplots import make_subplots from geopy.distance import geodesic from behavior.analyst import Analyst from utils.directoryUtil import DirectoryUtil as dir from algorithmContract.confBusiness import * import common.turbineInfo as turbineInfo class TemperatureEnvironmentAnalyst(Analyst): """ 风电机组大部件温升分析 """ def typeAnalyst(self): return "temperature_environment" def turbinesAnalysis(self, dataFrameMerge,outputAnalysisDir, confData: ConfBusiness): # 检查所需列是否存在 required_columns = {confData.field_env_temp, Field_NameOfTurbine} if not required_columns.issubset(dataFrameMerge.columns): raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}") turbineInfos = turbineInfo.loadTurbineInfo(confData.turbineInfoFilePathCSV) # 环境温度 分析 turbineEnvTempData =dataFrameMerge.groupby(Field_NameOfTurbine).agg( {confData.field_env_temp : 'median'}).reset_index(names=[Field_NameOfTurbine]) mergeData = self.merge_Data(Field_NameOfTurbine,turbineInfos, turbineEnvTempData,confData) self.draw(mergeData,outputAnalysisDir, confData) def merge_Data(self,fieldTurbineName, turbineInfos:pd.DataFrame, turbineEnvTempData, confData: ConfBusiness): """ 将每台机组的环境温度均值数据与机组信息,按机组合并 参数: turbineInfos (pandas.DataFrame): 机组信息数据 turbineEnvTempData (pandas.DataFrame): 每台机组的环境温度均值数据 返回: pandas.DataFrame: 每台机组的环境温度均值数据与机组信息合并数据 """ """ 合并类型how的选项包括: 'inner': 内连接,只保留两个DataFrame中都有的键的行。 'outer': 外连接,保留两个DataFrame中任一或两者都有的键的行。 'left': 左连接,保留左边DataFrame的所有键,以及右边DataFrame中匹配的键的行。 'right': 右连接,保留右边DataFrame的所有键,以及左边DataFrame中匹配的键的行。 """ # turbineEnvTempData[fieldTurbineName]=turbineEnvTempData[fieldTurbineName].astype(str) merge_data = pd.merge(turbineInfos, turbineEnvTempData, on=[fieldTurbineName], how='inner') return merge_data # 定义查找给定半径内点的函数 def find_points_within_radius(self, data, center, field_temperature_env, radius): points_within_radius = [] for index, row in data.iterrows(): distance = geodesic( (center[2], center[1]), (row['latitude'], row['longitude'])).meters if distance <= radius: points_within_radius.append( (row['turbine_name'], row[field_temperature_env])) return points_within_radius fieldTemperatureDiff="temperature_diff" def draw(self,dataFrame : pd.DataFrame, outputAnalysisDir,confData: ConfBusiness,charset=charset_unify): # 处理数据 dataFrame['new'] = dataFrame.loc[:, [Field_NameOfTurbine , 'longitude', 'latitude', confData.field_env_temp]].apply(tuple, axis=1) coordinates = dataFrame['new'].tolist() df = pd.DataFrame(coordinates, columns=[Field_NameOfTurbine, 'longitude', 'latitude', confData.field_env_temp]) # 查找半径内的点 points_within_radius = {coord: self.find_points_within_radius(dataFrame,coord,confData.field_env_temp,confData.rotor_diameter*10) for coord in coordinates} res = [] for center, nearby_points in points_within_radius.items(): current_temp = dataFrame[dataFrame[Field_NameOfTurbine] == center[0]][confData.field_env_temp].iloc[0] target_tuple = (center[0], current_temp) if target_tuple in nearby_points: nearby_points.remove(target_tuple) mean_temp = np.median([i[1] for i in nearby_points]) if nearby_points else current_temp res.append((center[0], nearby_points, mean_temp, current_temp)) res = pd.DataFrame(res, columns=[Field_NameOfTurbine, '周边机组', '周边机组温度', '当前机组温度']) res[self.fieldTemperatureDiff] = res['当前机组温度'] - res['周边机组温度'] fig, ax = plt.subplots(figsize=(16,8),dpi=96) # 设置x轴刻度值旋转角度为45度 plt.tick_params(axis='x', rotation=45) sns.barplot(x=Field_NameOfTurbine,y=self.fieldTemperatureDiff,data=res,ax=ax,color='dodgerblue') plt.axhline(y=5,ls=":",c="red")#添加水平直线 plt.axhline(y=-5,ls=":",c="red")#添加水平直线 ax.set_ylabel('temperature_difference') ax.set_title('temperature Bias') plt.savefig(outputAnalysisDir +'//'+ "{}环境温差Bias.png".format(confData.farm_name),bbox_inches='tight',dpi=120) fig2, ax2 = plt.subplots(figsize=(16,8),dpi=96) # 设置x轴刻度值旋转角度为45度 plt.tick_params(axis='x', rotation=45) sns.barplot(x=Field_NameOfTurbine ,y='当前机组温度',data=res,ax=ax2,color='dodgerblue') ax2.set_ylabel('temperature') ax2.set_title('temperature median') plt.savefig(outputAnalysisDir +'//'+ "{}环境温度均值.png".format(confData.farm_name),bbox_inches='tight',dpi=120)