windSpeedFrequencyAnalyst.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. import plotly.graph_objects as go
  5. import plotly.express as px
  6. from plotly.subplots import make_subplots
  7. from behavior.analystNotFilter import AnalystNotFilter
  8. from utils.directoryUtil import DirectoryUtil as dir
  9. import matplotlib.pyplot as plt
  10. from algorithmContract.confBusiness import *
  11. from algorithmContract.contract import Contract
  12. class WindSpeedFrequencyAnalyst(AnalystNotFilter):
  13. def typeAnalyst(self):
  14. return "wind_speed_frequency"
  15. # def filterCommon(self,dataFrame:pd.DataFrame, conf: Contract):
  16. # return dataFrame
  17. def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes):
  18. dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_WindSpeed,Field_ActiverPower])
  19. dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
  20. return self.windRoseAnalysis(dataFrameMerge, outputAnalysisDir, conf)
  21. def windRoseAnalysis(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, conf: Contract):
  22. # 检查所需列是否存在
  23. required_columns = {Field_NameOfTurbine, Field_WindSpeed}
  24. if not required_columns.issubset(dataFrameMerge.columns):
  25. raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}")
  26. wind_speed_bins = np.arange(0, 26, 0.5) # x轴风速范围 ,间隔0.5
  27. # 按设备名分组数据
  28. grouped = dataFrameMerge.groupby([Field_NameOfTurbine, Field_CodeOfTurbine])
  29. result_rows = []
  30. for name, group in grouped:
  31. # 2. 计算风速频率
  32. # 首先,我们需要确定风速的范围并计算每个风速的频数
  33. # wind_speeds = group[Field_WindSpeed].unique()
  34. # 计算风速频率,确保频率没有零值(用很小的数代替零)
  35. wind_speed_freq = np.histogram(group[Field_WindSpeed], bins=wind_speed_bins)[0]
  36. wind_speed_freq = np.maximum(wind_speed_freq, 0.01) / len(group[Field_WindSpeed]) * 100
  37. # 3. & 4. 确定y轴风速频率的范围和间隔(这里直接计算了频率,所以不需要手动设置间隔)
  38. # 我们已经计算了风速频率,因此不需要再手动设置y轴的间隔和范围
  39. # 5. 使用plotly绘制风速频率分布柱状图
  40. # 为了使用plotly绘制柱状图,我们需要将风速范围的中点作为x轴的值
  41. x_values = (wind_speed_bins[:-1] + wind_speed_bins[1:]) / 2
  42. # 创建柱状图
  43. fig = px.bar(x=x_values, y=wind_speed_freq)
  44. # 更新图形的布局
  45. fig.update_layout(
  46. title={
  47. 'text': f'风速频率: {name[0]}',
  48. # 'y': 0.95,
  49. 'x': 0.5,
  50. 'xanchor': 'center',
  51. 'yanchor': 'top'
  52. },
  53. xaxis=dict(
  54. title='风速 (m/s)',
  55. showgrid=True,
  56. range=[0, 26],
  57. dtick=1,
  58. tickangle=-45
  59. ),
  60. yaxis=dict(
  61. title='频率 (%)',
  62. showgrid=True,
  63. # range=[0, 1],
  64. ),
  65. margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距
  66. )
  67. # # 更新x轴和y轴的范围和标签
  68. # fig.update_yaxes(range=[0, max(wind_speed_freq) * 1.1 if max(wind_speed_freq) > 0 else 0.2], title='Frequency')
  69. # Save plot
  70. filePathOfImage = os.path.join(outputAnalysisDir, f"{name[0]}.png")
  71. fig.write_image(filePathOfImage, scale=3)
  72. filePathOfHtml = os.path.join(outputAnalysisDir, f"{name[0]}.html")
  73. fig.write_html(filePathOfHtml)
  74. result_rows.append({
  75. Field_Return_TypeAnalyst: self.typeAnalyst(),
  76. Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
  77. Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
  78. Field_CodeOfTurbine: name[1],
  79. Field_Return_FilePath: filePathOfImage,
  80. Field_Return_IsSaveDatabase: False
  81. })
  82. result_rows.append({
  83. Field_Return_TypeAnalyst: self.typeAnalyst(),
  84. Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
  85. Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
  86. Field_CodeOfTurbine: name[1],
  87. Field_Return_FilePath: filePathOfHtml,
  88. Field_Return_IsSaveDatabase: True
  89. })
  90. result_df = pd.DataFrame(result_rows)
  91. return result_df