powerOscillationAnalyst.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import os
  2. import matplotlib.pyplot as plt
  3. import pandas as pd
  4. import seaborn as sns
  5. from algorithmContract.confBusiness import *
  6. from behavior.analyst import Analyst
  7. from utils.directoryUtil import DirectoryUtil as dir
  8. class PowerOscillationAnalyst(Analyst):
  9. """
  10. 风电机组功率震荡分析
  11. """
  12. def typeAnalyst(self):
  13. return "power_diff"
  14. def turbineAnalysis(self,
  15. dataFrame,
  16. outputAnalysisDir,
  17. outputFilePath,
  18. confData: ConfBusiness,
  19. turbineName):
  20. self.power_diff(dataFrame, outputFilePath,
  21. confData.field_power,confData.field_rotor_speed)
  22. def power_diff(self, dataFrame, outputFilePath, field_Active_Power, field_Rotor_Speed):
  23. # Floor the power column to the nearest 10
  24. dataFrame['power_col_floor'] = (
  25. dataFrame[field_Active_Power] // 10 * 10).astype('int32')
  26. # Group by the floored power column
  27. grouped = dataFrame.groupby('power_col_floor')
  28. # Calculate max, min, and diff of generator speed within each group
  29. agg_df = grouped[field_Rotor_Speed].agg(
  30. speed_max='max',
  31. speed_min='min'
  32. )
  33. agg_df['speed_diff'] = agg_df['speed_max'] - agg_df['speed_min']
  34. # Sort by the floored power column
  35. agg_df = agg_df.sort_index()
  36. # Write the result to a CSV file
  37. agg_df.to_csv(outputFilePath)
  38. def turbinesAnalysis(self,dataFrameMerge,outputAnalysisDir, confData: ConfBusiness):
  39. self.plot_power_oscillations(outputAnalysisDir,confData.farm_name)
  40. def plot_power_oscillations(self, csvFileDirOfCp, farm_name, encoding='utf-8'):
  41. """
  42. Plot TSR trend from CSV files in a given input path and save the plots to an output path.
  43. Parameters:
  44. - csvFileDirOfCp: str, path to the directory containing input CSV files.
  45. - farm_name: str, name of the wind farm.
  46. - encoding: str, encoding of the input CSV files. Defaults to 'utf-8'.
  47. """
  48. sns.set_palette('deep')
  49. field_Name_Turbine = "turbine_name"
  50. x_name = 'power_col_floor'
  51. y_name = 'speed_diff'
  52. # 初始化结果DataFrame
  53. res = pd.DataFrame()
  54. # 遍历输入路径下的所有文件
  55. for root, dir_names, file_names in dir.list_directory(csvFileDirOfCp):
  56. for file_name in file_names:
  57. if not file_name.endswith(CSVSuffix):
  58. continue
  59. file_path = os.path.join(root, file_name)
  60. frame = pd.read_csv(file_path, encoding=encoding)
  61. # 获取输出文件名前缀
  62. turbine_name = file_name.split(CSVSuffix)[0]
  63. # 添加设备名作为新列
  64. frame[field_Name_Turbine] = turbine_name
  65. selected_data = frame.loc[:, [field_Name_Turbine, x_name, y_name]]
  66. res = pd.concat([res, selected_data], axis=0)
  67. # 重置索引
  68. ress = res.reset_index(drop=True)
  69. # 绘制所有设备的功率震荡图
  70. fig, ax = plt.subplots(figsize=(16, 8))
  71. ax = sns.lineplot(x=x_name, y=y_name, data=ress, hue=field_Name_Turbine)
  72. ax.set_title(f'功率震荡-{self.turbineModelInfo[Field_MachineTypeCode].iloc[0]}')
  73. plt.legend(ncol=4)
  74. plt.savefig(csvFileDirOfCp+ r'/{}-Power-Oscillation.png'.format(farm_name), bbox_inches='tight', dpi=300)
  75. plt.close()
  76. # 分组绘制每个设备的功率震荡图
  77. grouped = ress.groupby(field_Name_Turbine)
  78. for name, group in grouped:
  79. color = ["lightgrey"] * len(ress[field_Name_Turbine].unique())
  80. fig, ax = plt.subplots(figsize=(8, 8))
  81. ax = sns.lineplot(x=x_name, y=y_name, data=ress, hue=field_Name_Turbine, palette=sns.color_palette(color), legend=False)
  82. ax = sns.lineplot(x=x_name, y=y_name, data=group, color='darkblue', legend=False)
  83. ax.set_title('turbine_name={}'.format(name))
  84. plt.savefig(csvFileDirOfCp+ r'/{}.png'.format(name), bbox_inches='tight', dpi=120)
  85. plt.close()