123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import os
- import pandas as pd
- import numpy as np
- import plotly.graph_objects as go
- import plotly.express as px
- from plotly.subplots import make_subplots
- from behavior.analystNotFilter import AnalystNotFilter
- from utils.directoryUtil import DirectoryUtil as dir
- import matplotlib.pyplot as plt
- from algorithmContract.confBusiness import *
- from algorithmContract.contract import Contract
- class WindSpeedFrequencyAnalyst(AnalystNotFilter):
- def typeAnalyst(self):
- return "wind_speed_frequency"
-
- # def filterCommon(self,dataFrame:pd.DataFrame, conf: Contract):
- # return dataFrame
- def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes):
- dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_WindSpeed,Field_ActiverPower])
- turbineInfos = self.common.getTurbineInfos(conf.dataContract.dataFilter.powerFarmID, turbineCodes,
- self.turbineInfo)
- dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
- return self.windRoseAnalysis(dataFrameMerge, turbineInfos, outputAnalysisDir, conf)
- def windRoseAnalysis(self, dataFrameMerge: pd.DataFrame, turbineModelInfo: pd.Series, outputAnalysisDir, conf: Contract):
- # 检查所需列是否存在
- required_columns = {Field_NameOfTurbine, Field_WindSpeed}
- if not required_columns.issubset(dataFrameMerge.columns):
- raise ValueError(f"DataFrame缺少必要的列。需要的列有: {required_columns}")
- wind_speed_bins = np.arange(0, 26, 0.5) # x轴风速范围 ,间隔0.5
- # 按设备名分组数据
- grouped = dataFrameMerge.groupby([Field_NameOfTurbine, Field_CodeOfTurbine])
- turbine_data_list = []
- result_rows = []
- for name, group in grouped:
- # 2. 计算风速频率
- # 首先,我们需要确定风速的范围并计算每个风速的频数
- # wind_speeds = group[Field_WindSpeed].unique()
- # 计算风速频率,确保频率没有零值(用很小的数代替零)
- wind_speed_freq = np.histogram(group[Field_WindSpeed], bins=wind_speed_bins)[0]
- wind_speed_freq = np.maximum(wind_speed_freq, 0.01) / len(group[Field_WindSpeed]) * 100
- # 3. & 4. 确定y轴风速频率的范围和间隔(这里直接计算了频率,所以不需要手动设置间隔)
- # 我们已经计算了风速频率,因此不需要再手动设置y轴的间隔和范围
- # 5. 使用plotly绘制风速频率分布柱状图
- # 为了使用plotly绘制柱状图,我们需要将风速范围的中点作为x轴的值
- x_values = (wind_speed_bins[:-1] + wind_speed_bins[1:]) / 2
- # 创建柱状图
- fig = px.bar(x=x_values, y=wind_speed_freq)
- # 更新图形的布局
- fig.update_layout(
- title={
- 'text': f'风速频率: {name[0]}',
- # 'y': 0.95,
- 'x': 0.5,
- 'xanchor': 'center',
- 'yanchor': 'top'
- },
- xaxis=dict(
- title='风速 (m/s)',
- showgrid=True,
- range=[0, 26],
- dtick=1,
- tickangle=-45
- ),
- yaxis=dict(
- title='频率 (%)',
- showgrid=True,
- # range=[0, 1],
- ),
- margin=dict(t=50, b=10) # t为顶部(top)间距,b为底部(bottom)间距
- )
- # # 更新x轴和y轴的范围和标签
- # fig.update_yaxes(range=[0, max(wind_speed_freq) * 1.1 if max(wind_speed_freq) > 0 else 0.2], title='Frequency')
- # 确保从 Series 中提取的是具体的值
- engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "")
- if isinstance(engineTypeCode, pd.Series):
- engineTypeCode = engineTypeCode.iloc[0]
- engineTypeName = turbineModelInfo.get(Field_MachineTypeCode, "")
- if isinstance(engineTypeName, pd.Series):
- engineTypeName = engineTypeName.iloc[0]
- # 构建最终的JSON对象
- json_output = {
- "analysisTypeCode": "风速频率分析",
- "engineCode": engineTypeCode,
- "engineTypeName": engineTypeName,
- "xaixs": "风速(m/s)",
- "yaixs": "频率(%)",
- "data": [{
- "engineName": name[0],
- "engineCode": name[1],
- "title": f' 风速频率:{name[0]}',
- "xData": x_values.tolist(),
- "yData": wind_speed_freq.tolist(),
- }]
- }
- # Save plot
- filePathOfImage = os.path.join(outputAnalysisDir, f"{name[0]}.png")
- fig.write_image(filePathOfImage, scale=3)
- # filePathOfHtml = os.path.join(outputAnalysisDir, f"{name[0]}.html")
- # fig.write_html(filePathOfHtml)
- # 将JSON对象保存到文件
- output_json_path = os.path.join(outputAnalysisDir, f"wind_Speed_Frequency{name[0]}.json")
- with open(output_json_path, 'w', encoding='utf-8') as f:
- import json
- json.dump(json_output, f, ensure_ascii=False, indent=4)
-
- result_rows.append({
- Field_Return_TypeAnalyst: self.typeAnalyst(),
- Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
- Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
- Field_CodeOfTurbine: name[1],
- Field_Return_FilePath: filePathOfImage,
- Field_Return_IsSaveDatabase: False
- })
- result_rows.append({
- Field_Return_TypeAnalyst: self.typeAnalyst(),
- Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
- Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
- Field_CodeOfTurbine: name[1],
- Field_MillTypeCode: 'total',
- Field_Return_FilePath: output_json_path,
- Field_Return_IsSaveDatabase: True
- })
- result_df = pd.DataFrame(result_rows)
- return result_df
-
|