ratedWindSpeedAnalyst.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import os
  2. import pandas as pd
  3. import plotly.graph_objects as go
  4. from algorithmContract.confBusiness import *
  5. from algorithmContract.contract import Contract
  6. from behavior.analystWithGoodBadPoint import AnalystWithGoodBadPoint
  7. class RatedWindSpeedAnalyst(AnalystWithGoodBadPoint):
  8. """
  9. 风电机组额定风速分析。
  10. 秒级scada数据运算太慢,建议使用分钟级scada数据
  11. """
  12. def typeAnalyst(self):
  13. return "rated_windspeed"
  14. def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes):
  15. # dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_WindSpeed,Field_ActiverPower])
  16. # dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
  17. dictionary = self.processTurbineData(turbineCodes, conf,
  18. [Field_DeviceCode, Field_Time, Field_WindSpeed, Field_ActiverPower])
  19. turbineInfos = self.common.getTurbineInfos(conf.dataContract.dataFilter.powerFarmID, turbineCodes,
  20. self.turbineInfo)
  21. dataFrameMerge = self.userDataFrame(dictionary, conf.dataContract.configAnalysis, self)
  22. return self.draw(dataFrameMerge, turbineInfos, outputAnalysisDir, conf)
  23. def draw(self, dataFrameMerge: pd.DataFrame, turbineModelInfo: pd.Series, outputAnalysisDir, conf: Contract):
  24. """
  25. 绘制并保存满发风速区间数据计数图。
  26. 参数:
  27. dataFrameMerge (pd.DataFrame): 包含数据的DataFrame,需要包含设备名、风速和功率列。
  28. outputAnalysisDir (str): 分析输出目录。
  29. confData (ConfBusiness): 配置
  30. """
  31. # 初始化结果列表
  32. res = []
  33. # 按设备名分组并计算统计数据
  34. grouped = dataFrameMerge.groupby(Field_NameOfTurbine)
  35. for name, group in grouped:
  36. group = group[group[Field_WindSpeed] >= 11]
  37. res.append([name, group[Field_ActiverPower].min(), group[Field_ActiverPower].max(
  38. ), group[Field_ActiverPower].median(), group.shape[0]])
  39. # 创建结果DataFrame
  40. data = pd.DataFrame(res, columns=[
  41. Field_NameOfTurbine, 'power-min', 'power-max', 'power-median', 'count'])
  42. fig = go.Figure(data=[go.Bar(
  43. x=data[Field_NameOfTurbine],
  44. y=data['count'],
  45. marker_color='dodgerblue'
  46. )
  47. ]
  48. )
  49. fig.update_layout(
  50. title={
  51. "text": f'额定风速间隔数据计数',
  52. 'x': 0.5
  53. },
  54. xaxis=dict(
  55. title='机组',
  56. tickangle=-45
  57. ),
  58. yaxis=dict(
  59. title='总数'
  60. )
  61. )
  62. # 确保从 Series 中提取的是具体的值
  63. engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "")
  64. if isinstance(engineTypeCode, pd.Series):
  65. engineTypeCode = engineTypeCode.iloc[0]
  66. engineTypeName = turbineModelInfo.get(Field_MachineTypeCode, "")
  67. if isinstance(engineTypeName, pd.Series):
  68. engineTypeName = engineTypeName.iloc[0]
  69. # 构建最终的JSON对象
  70. json_output = {
  71. "analysisTypeCode": "额定风速分析",
  72. "engineCode": engineTypeCode,
  73. "engineTypeName": engineTypeName,
  74. "xaixs": "机组",
  75. "yaixs": "总数",
  76. "data": [{
  77. "engineName": "",
  78. "engineCode": "",
  79. "title": f' 额定风速间隔数据计数',
  80. "xData": data[Field_NameOfTurbine].tolist(),
  81. "yData": data['count'].tolist(),
  82. }]
  83. }
  84. result_rows = []
  85. # 保存图像
  86. pngFileName = '风速区间数据计数.png'
  87. pngFilePath = os.path.join(outputAnalysisDir, pngFileName)
  88. fig.write_image(pngFilePath, scale=3)
  89. # 保存HTML
  90. # htmlFileName = '风速区间数据计数.html'
  91. # htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
  92. # fig.write_html(htmlFilePath)
  93. # 将JSON对象保存到文件
  94. output_json_path = os.path.join(outputAnalysisDir, f"rated_WindSpeed.json")
  95. with open(output_json_path, 'w', encoding='utf-8') as f:
  96. import json
  97. json.dump(json_output, f, ensure_ascii=False, indent=4)
  98. result_rows.append({
  99. Field_Return_TypeAnalyst: self.typeAnalyst(),
  100. Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
  101. Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
  102. Field_CodeOfTurbine: 'total',
  103. Field_Return_FilePath: pngFilePath,
  104. Field_Return_IsSaveDatabase: False
  105. })
  106. result_rows.append({
  107. Field_Return_TypeAnalyst: self.typeAnalyst(),
  108. Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
  109. Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
  110. Field_CodeOfTurbine: 'total',
  111. Field_MillTypeCode: 'total',
  112. Field_Return_FilePath: output_json_path,
  113. Field_Return_IsSaveDatabase: True
  114. })
  115. result_df = pd.DataFrame(result_rows)
  116. return result_df