cpTrendAnalyst.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import os
  2. import pandas as pd
  3. import numpy as np
  4. from plotly.subplots import make_subplots
  5. import plotly.graph_objects as go
  6. import matplotlib.pyplot as plt
  7. from .analyst import Analyst
  8. from .utils.directoryUtil import DirectoryUtil as dir
  9. from confBusiness import ConfBusiness
  10. class CpTrendAnalyst(Analyst):
  11. """
  12. 风电机组风能利用系数时序分析
  13. """
  14. def typeAnalyst(self):
  15. return "cp_trend"
  16. def turbineAnalysis(self,
  17. dataFrame,
  18. outputAnalysisDir,
  19. outputFilePath,
  20. confData: ConfBusiness,
  21. turbineName):
  22. self.cp_trend(dataFrame, outputFilePath,
  23. confData.field_turbine_time, confData.field_wind_speed, confData.field_rotor_speed, confData.field_power, confData.field_pitch_angle1,
  24. confData.rotor_diameter, confData.density_air)
  25. def cp_trend(self, dataFrame, outputFilePath, time_col, wind_speed_col, generator_speed_col, power_col, pitch_col, rotor_diameter, density_air):
  26. dataFrame['time_day'] = dataFrame[time_col].dt.date
  27. # Assign columns and calculate 'cp'
  28. dataFrame['wind_speed'] = dataFrame[wind_speed_col].astype(float)
  29. dataFrame['rotor_speed'] = dataFrame[generator_speed_col].astype(float)
  30. dataFrame['power'] = dataFrame[power_col]
  31. # Power coefficient calculation
  32. rotor_diameter = pd.to_numeric(rotor_diameter, errors='coerce')
  33. air_density = pd.to_numeric(rotor_diameter, errors='coerce')
  34. # Calculate cp
  35. dataFrame['cp'] = dataFrame['power'] * 1000 / (0.5 * np.pi * air_density * (
  36. rotor_diameter ** 2) / 4 * dataFrame['wind_speed'] ** 3)
  37. # Group by day and aggregate
  38. grouped = dataFrame.groupby('time_day').agg({
  39. time_col: 'min', # Assuming time_col is the datetime column for minimum time
  40. 'wind_speed': 'mean',
  41. 'rotor_speed': 'mean',
  42. 'cp': ['mean', 'max', 'min']
  43. }).reset_index()
  44. # Rename columns post aggregation for clarity
  45. grouped.columns = ['time_day', 'time_', 'wind_speed',
  46. 'rotor_speed', 'cp', 'cp_max', 'cp_min']
  47. # Sort by day
  48. grouped = grouped.sort_values('time_day')
  49. # Write to CSV
  50. grouped.to_csv(outputFilePath, index=False)
  51. def turbinesAnalysis(self, dataFrameMerge, outputAnalysisDir, confData: ConfBusiness):
  52. self.create_cp_trend_plots(outputAnalysisDir, confData.farm_name)
  53. def create_cp_trend_plots(self, csvFileDirOfCp, farm_name, encoding='utf-8'):
  54. """
  55. Generates and saves error bar plots for CP trend data stored in CSV files.
  56. Parameters:
  57. - csvFileDirOfCp: Path to the directory containing the input CSV files.
  58. - farm_name: Name of the farm, used to format the output path.
  59. - encoding: str, encoding of the input CSV files. Defaults to 'utf-8'.
  60. """
  61. time_day = 'time_day'
  62. y_name = 'cp'
  63. y_min = 'cp_min'
  64. y_max = 'cp_max'
  65. split_way = '_cp_trend.csv'
  66. # Create the output directory if it does not exist
  67. if not os.path.exists(csvFileDirOfCp):
  68. os.makedirs(csvFileDirOfCp)
  69. # Walk through the input directory to process each CSV file
  70. for root, dir_names, file_names in dir.list_directory(csvFileDirOfCp):
  71. for file_name in file_names:
  72. if not file_name.endswith(".csv"):
  73. continue
  74. # Read each CSV file
  75. data = pd.read_csv(os.path.join(
  76. root, file_name), encoding=encoding)
  77. data.loc[:, time_day] = pd.to_datetime(data.loc[:, time_day])
  78. data[y_min] = data[y_name] - data[y_min]
  79. data[y_max] = data[y_max] - data[y_name]
  80. turbine_name = file_name.split(split_way)[0]
  81. # Generate the plot
  82. fig, ax = plt.subplots()
  83. ax.errorbar(x=data[time_day], y=data[y_name], yerr=[data[y_min], data[y_max]],
  84. fmt='o', capsize=4, elinewidth=2, ecolor='lightgrey', mfc='dodgerblue')
  85. ax.set_xlabel('time')
  86. ax.set_ylabel('Cp')
  87. # ax.set_ylim(-0.2, 8)
  88. ax.set_title('{}={}'.format('turbine_name', turbine_name))
  89. # 旋转x轴刻度标签
  90. plt.xticks(rotation=45)
  91. # Save the plot
  92. plt.savefig(os.path.join(csvFileDirOfCp, "{}.png".format(
  93. turbine_name)), bbox_inches='tight', dpi=120)
  94. plt.close()