temperatureEnvironmentAnalyst.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. import pandas as pd
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. import plotly.graph_objects as go
  8. from plotly.subplots import make_subplots
  9. from geopy.distance import geodesic
  10. from behavior.analyst import Analyst
  11. from utils.directoryUtil import DirectoryUtil as dir
  12. from algorithmContract.confBusiness import *
  13. import common.turbineInfo as turbineInfo
  14. class TemperatureEnvironmentAnalyst(Analyst):
  15. """
  16. 风电机组大部件温升分析
  17. """
  18. def typeAnalyst(self):
  19. return "temperature_environment"
  20. def turbinesAnalysis(self, dataFrameMerge,outputAnalysisDir, confData: ConfBusiness):
  21. # 检查所需列是否存在
  22. required_columns = {confData.field_env_temp,
  23. Field_NameOfTurbine}
  24. if not required_columns.issubset(dataFrameMerge.columns):
  25. raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}")
  26. turbineInfos = turbineInfo.loadTurbineInfo(confData.turbineInfoFilePathCSV)
  27. # 环境温度 分析
  28. turbineEnvTempData =dataFrameMerge.groupby(Field_NameOfTurbine).agg(
  29. {confData.field_env_temp : 'median'}).reset_index(names=[Field_NameOfTurbine])
  30. mergeData = self.merge_Data(Field_NameOfTurbine,turbineInfos, turbineEnvTempData,confData)
  31. self.draw(mergeData,outputAnalysisDir, confData)
  32. def merge_Data(self,fieldTurbineName, turbineInfos:pd.DataFrame, turbineEnvTempData, confData: ConfBusiness):
  33. """
  34. 将每台机组的环境温度均值数据与机组信息,按机组合并
  35. 参数:
  36. turbineInfos (pandas.DataFrame): 机组信息数据
  37. turbineEnvTempData (pandas.DataFrame): 每台机组的环境温度均值数据
  38. 返回:
  39. pandas.DataFrame: 每台机组的环境温度均值数据与机组信息合并数据
  40. """
  41. """
  42. 合并类型how的选项包括:
  43. 'inner': 内连接,只保留两个DataFrame中都有的键的行。
  44. 'outer': 外连接,保留两个DataFrame中任一或两者都有的键的行。
  45. 'left': 左连接,保留左边DataFrame的所有键,以及右边DataFrame中匹配的键的行。
  46. 'right': 右连接,保留右边DataFrame的所有键,以及左边DataFrame中匹配的键的行。
  47. """
  48. # turbineEnvTempData[fieldTurbineName]=turbineEnvTempData[fieldTurbineName].astype(str)
  49. merge_data = pd.merge(turbineInfos, turbineEnvTempData, on=[fieldTurbineName], how='inner')
  50. return merge_data
  51. # 定义查找给定半径内点的函数
  52. def find_points_within_radius(self, data, center, field_temperature_env, radius):
  53. points_within_radius = []
  54. for index, row in data.iterrows():
  55. distance = geodesic(
  56. (center[2], center[1]), (row['latitude'], row['longitude'])).meters
  57. if distance <= radius:
  58. points_within_radius.append(
  59. (row['turbine_name'], row[field_temperature_env]))
  60. return points_within_radius
  61. fieldTemperatureDiff="temperature_diff"
  62. def draw(self,dataFrame : pd.DataFrame, outputAnalysisDir,confData: ConfBusiness,charset=charset_unify):
  63. # 处理数据
  64. dataFrame['new'] = dataFrame.loc[:, [Field_NameOfTurbine , 'longitude', 'latitude', confData.field_env_temp]].apply(tuple, axis=1)
  65. coordinates = dataFrame['new'].tolist()
  66. df = pd.DataFrame(coordinates, columns=[Field_NameOfTurbine, 'longitude', 'latitude', confData.field_env_temp])
  67. # 查找半径内的点
  68. points_within_radius = {coord: self.find_points_within_radius(dataFrame,coord,confData.field_env_temp,confData.rotor_diameter*10) for coord in coordinates}
  69. res = []
  70. for center, nearby_points in points_within_radius.items():
  71. current_temp = dataFrame[dataFrame[Field_NameOfTurbine] == center[0]][confData.field_env_temp].iloc[0]
  72. target_tuple = (center[0], current_temp)
  73. if target_tuple in nearby_points:
  74. nearby_points.remove(target_tuple)
  75. mean_temp = np.median([i[1] for i in nearby_points]) if nearby_points else current_temp
  76. res.append((center[0], nearby_points, mean_temp, current_temp))
  77. res = pd.DataFrame(res, columns=[Field_NameOfTurbine, '周边机组', '周边机组温度', '当前机组温度'])
  78. res[self.fieldTemperatureDiff] = res['当前机组温度'] - res['周边机组温度']
  79. fig, ax = plt.subplots(figsize=(16,8),dpi=96)
  80. # 设置x轴刻度值旋转角度为45度
  81. plt.tick_params(axis='x', rotation=45)
  82. sns.barplot(x=Field_NameOfTurbine,y=self.fieldTemperatureDiff,data=res,ax=ax,color='dodgerblue')
  83. plt.axhline(y=5,ls=":",c="red")#添加水平直线
  84. plt.axhline(y=-5,ls=":",c="red")#添加水平直线
  85. ax.set_ylabel('temperature_difference')
  86. ax.set_title('temperature Bias')
  87. plt.savefig(outputAnalysisDir +'//'+ "{}环境温差Bias.png".format(confData.farm_name),bbox_inches='tight',dpi=120)
  88. fig2, ax2 = plt.subplots(figsize=(16,8),dpi=96)
  89. # 设置x轴刻度值旋转角度为45度
  90. plt.tick_params(axis='x', rotation=45)
  91. sns.barplot(x=Field_NameOfTurbine ,y='当前机组温度',data=res,ax=ax2,color='dodgerblue')
  92. ax2.set_ylabel('temperature')
  93. ax2.set_title('temperature median')
  94. plt.savefig(outputAnalysisDir +'//'+ "{}环境温度均值.png".format(confData.farm_name),bbox_inches='tight',dpi=120)