tsrAnalyst.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. from matplotlib.ticker import MultipleLocator
  8. from behavior.analystExcludeRatedPower import AnalystExcludeRatedPower
  9. from utils.directoryUtil import DirectoryUtil as dir
  10. from algorithmContract.confBusiness import *
  11. class TSRAnalyst(AnalystExcludeRatedPower):
  12. """
  13. 风电机组叶尖速比分析
  14. """
  15. def typeAnalyst(self):
  16. return "tsr"
  17. def turbineAnalysis(self,
  18. dataFrame,
  19. outputAnalysisDir,
  20. outputFilePath,
  21. confData: ConfBusiness,
  22. turbineName):
  23. self.tsr(dataFrame, outputFilePath,
  24. confData.field_wind_speed, confData.field_rotor_speed, confData.field_power, confData.field_pitch_angle1, confData.rotor_diameter)
  25. def tsr(self, dataFrame, output_path, field_wind_speed, field_rotort_speed, field_power_active, field_angle_pitch, rotor_diameter):
  26. # Calculate 'power_floor'
  27. dataFrame['power_floor'] = (
  28. dataFrame[field_power_active] / 10).astype(int) * 10
  29. # Ensure the necessary columns are of float type
  30. dataFrame['wind_speed'] = dataFrame[field_wind_speed].astype(float)
  31. dataFrame['rotor_speed'] = dataFrame[field_rotort_speed].astype(float)
  32. # rotor_diameter = pd.to_numeric(rotor_diameter, errors='coerce')
  33. # # Calculate TSR
  34. # dataFrame['tsr'] = (dataFrame['rotor_speed'] * 0.104667 *
  35. # (rotor_diameter / 2)) / dataFrame['wind_speed']
  36. # Group by 'power_floor' and calculate mean, max, and min of TSR
  37. grouped = dataFrame.groupby('power_floor').agg({
  38. 'wind_speed': 'mean',
  39. 'rotor_speed': 'mean',
  40. 'tsr': ['mean', 'max', 'min']
  41. }).reset_index()
  42. # Rename columns for clarity post aggregation
  43. grouped.columns = ['power_floor', 'wind_speed',
  44. 'rotor_speed', 'tsr', 'tsr_max', 'tsr_min']
  45. # Sort by 'power_floor'
  46. grouped = grouped.sort_values('power_floor')
  47. # Write the aggregated dataFrame to a new CSV file
  48. grouped.to_csv(output_path, index=False)
  49. def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness):
  50. self.plot_tsr_distribution(outputAnalysisDir, confData)
  51. def plot_tsr_distribution(self, csvFileDirOfCp, confData: ConfBusiness, encoding='utf-8'):
  52. """
  53. Generates tsr distribution plots for turbines in a wind farm.
  54. Parameters:
  55. - csvFileDirOfCp: str, path to the directory containing input CSV files.
  56. - farm_name: str, name of the wind farm.
  57. - encoding: str, encoding of the input CSV files. Defaults to 'utf-8'.
  58. """
  59. field_Name_Turbine = "turbine_name"
  60. x_name = 'power_floor'
  61. y_name = 'tsr'
  62. upLimitOfPower = confData.rated_power*0.9
  63. upLimitOfTSR = 20
  64. # 设置绘图样式
  65. sns.set_palette('deep')
  66. # 初始化结果DataFrame
  67. res = pd.DataFrame()
  68. # 遍历输入目录中的所有文件
  69. for root, dir_names, file_names in dir.list_directory(csvFileDirOfCp):
  70. for file_name in file_names:
  71. if not file_name.endswith(CSVSuffix):
  72. continue
  73. file_path = os.path.join(root, file_name)
  74. # 读取CSV文件
  75. frame = pd.read_csv(file_path, encoding=encoding)
  76. frame = frame[(frame[x_name] > 0)]
  77. # 提取设备名
  78. turbine_name = file_name.split(CSVSuffix)[0]
  79. # 添加设备名作为新列
  80. frame[field_Name_Turbine] = turbine_name
  81. # 选择需要的列并合并到结果DataFrame中
  82. res = pd.concat(
  83. [res, frame.loc[:, [field_Name_Turbine, x_name, y_name]]], axis=0)
  84. # 重置索引
  85. ress = res.reset_index()
  86. # 绘制全场TSR分布图
  87. fig, ax = plt.subplots(figsize=(16, 8))
  88. ax = sns.lineplot(x=x_name, y=y_name, data=ress,
  89. hue=field_Name_Turbine)
  90. ax.xaxis.set_major_locator(MultipleLocator(200)) # 创建一个刻度 ,将定位器应用到y轴上
  91. ax.set_xlim(0, upLimitOfPower)
  92. ax.yaxis.set_major_locator(MultipleLocator(
  93. confData.graphSets["tsr"]["step"] if not self.common.isNone(confData.graphSets["tsr"]["step"]) else 5)) # 创建一个刻度 ,将定位器应用到y轴上
  94. ax.set_ylim(confData.graphSets["tsr"]["min"] if not self.common.isNone(confData.graphSets["tsr"]["min"]) else 0,
  95. confData.graphSets["tsr"]["max"] if not self.common.isNone(confData.graphSets["tsr"]["max"]) else upLimitOfTSR)
  96. ax.set_title('TSR-Distibute')
  97. # plt.legend(ncol=4)
  98. plt.xticks(rotation=45) # 旋转45度
  99. plt.legend(title='turbine', bbox_to_anchor=(1.02, 0.5),
  100. ncol=2, loc='center left', borderaxespad=0.)
  101. plt.savefig(csvFileDirOfCp + r"/{}-TSR-Distibute.png".format(confData.farm_name),
  102. bbox_inches='tight', dpi=300)
  103. plt.close(fig)
  104. # 绘制每个设备的TSR分布图
  105. grouped = ress.groupby(field_Name_Turbine)
  106. for name, group in grouped:
  107. color = ["lightgrey"] * len(ress[field_Name_Turbine].unique())
  108. fig, ax = plt.subplots(figsize=(8, 8))
  109. ax = sns.lineplot(x=x_name, y=y_name, data=ress, hue=field_Name_Turbine,
  110. palette=sns.set_palette(color), legend=False)
  111. ax = sns.lineplot(x=x_name, y=y_name, data=group,
  112. color='darkblue', legend=False)
  113. ax.xaxis.set_major_locator(
  114. MultipleLocator(200)) # 创建一个刻度 ,将定位器应用到y轴上
  115. ax.set_xlim(0, upLimitOfPower)
  116. ax.yaxis.set_major_locator(MultipleLocator(
  117. confData.graphSets["tsr"]["step"] if not self.common.isNone(confData.graphSets["tsr"]["step"]) else 5)) # 创建一个刻度 ,将定位器应用到y轴上
  118. ax.set_ylim(confData.graphSets["tsr"]["min"] if not self.common.isNone(confData.graphSets["tsr"]["min"]) else 0,
  119. confData.graphSets["tsr"]["max"] if not self.common.isNone(confData.graphSets["tsr"]["max"]) else upLimitOfTSR)
  120. ax.set_title('turbine name={}'.format(name))
  121. plt.xticks(rotation=45) # 旋转45度
  122. plt.savefig(csvFileDirOfCp + r"/{}.png".format(name),
  123. bbox_inches='tight', dpi=120)
  124. plt.close(fig)