dataMarker.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. import os
  2. import re
  3. import pandas as pd
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. from matplotlib.pyplot import MultipleLocator
  7. import math
  8. import pdb
  9. from algorithmContract.confBusiness import * #将这个包里的全部加载
  10. intervalPower = 25
  11. intervalWindspeed = 0.25
  12. # 限功率识别策略(参考):1. 功率<1100,and 叶片角度>0.5 ; 2. 功率<1250 and 叶片角度>1.5 ; 3. 功率<1400 and 叶片角度>2.5 ;
  13. class DataMarker:
  14. #选取时间、风速、功率数据
  15. def preprocessData(self,dataFrame:pd.DataFrame):
  16. timeStamp = dataFrame[Field_Time]
  17. activePower = dataFrame[Field_ActiverPower]
  18. windSpeed = dataFrame[Field_WindSpeed]
  19. dataFramePartOfSCADA = pd.concat([timeStamp,activePower,windSpeed], axis=1)
  20. return dataFramePartOfSCADA
  21. #计算分仓数目
  22. def calculateIntervals(self,activePowerMax, ratedPower, windSpeedCutOut):
  23. binNumOfPower = math.floor((activePowerMax) / intervalPower) + 1 if (activePowerMax) >= ratedPower else math.floor(ratedPower / intervalPower)
  24. binNumOfWindSpeed = math.ceil(windSpeedCutOut / intervalWindspeed)
  25. return binNumOfPower, binNumOfWindSpeed
  26. def calculateTopP(self,activePowerMax,ratedPower):
  27. TopP = 0
  28. if activePowerMax >= ratedPower:
  29. TopP = math.floor((activePowerMax - ratedPower) / intervalPower) + 1
  30. else:
  31. TopP = 0
  32. return TopP
  33. def chooseData(self,dataFramePartOfSCADA:pd.DataFrame,dataFrame:pd.DataFrame):
  34. lowLimitActivePower=10.0
  35. lowLimitWindSpeed=0.0
  36. # 初始化标签列
  37. # SM1 = dataFramePartOfSCADA.shape
  38. # AA1 = SM1[0]
  39. # lab = [[0] for _ in range(AA1)]
  40. # lab = pd.DataFrame(lab,columns=['lab'])
  41. # dataFramePartOfSCADA = pd.concat([dataFramePartOfSCADA,lab],axis=1) #在tpv后加一列标签列
  42. dataFramePartOfSCADA[Field_LableFlag]=0
  43. dataFramePartOfSCADA = dataFramePartOfSCADA.values
  44. SM = dataFramePartOfSCADA.shape #(52561,4)
  45. # SM = dataFramePartOfSCADA[((dataFramePartOfSCADA[Field_ActiverPower].notna()) & (dataFramePartOfSCADA[Field_WindSpeed].notna()))].shape #(52561,4)
  46. AA = SM[0] -1
  47. nCounter1 = 0
  48. DzMarch809_0 = np.zeros((AA, 3))
  49. Point_line = np.zeros(AA, dtype=int)
  50. APower = dataFrame[Field_ActiverPower].values
  51. WSpeed = dataFrame[Field_WindSpeed ].values
  52. for i in range(AA):
  53. if (APower[i] > lowLimitActivePower) & (WSpeed[i] > lowLimitWindSpeed):
  54. nCounter1 += 1
  55. DzMarch809_0[nCounter1-1, 0] = WSpeed[i]
  56. DzMarch809_0[nCounter1-1, 1] = APower[i]
  57. Point_line[nCounter1-1] = i+1
  58. if APower[i] <= 10:
  59. dataFramePartOfSCADA[i,SM[1]-1] = -1
  60. DzMarch809 = DzMarch809_0[:nCounter1, :]
  61. return DzMarch809,nCounter1,dataFramePartOfSCADA,Point_line,SM
  62. def gridCount(self,binNumOfWindSpeed,binNumOfPower,nCounter1,DzMarch809):
  63. # 遍历有效数据
  64. XBoxNumber = np.ones((binNumOfPower, binNumOfWindSpeed),dtype=int)
  65. for i in range(nCounter1):
  66. for m in range(1, binNumOfPower + 1):
  67. if (DzMarch809[i,1] > (m - 1) * intervalPower) and (DzMarch809[i,1] <= m * intervalPower):
  68. nWhichP = m
  69. break
  70. for n in range(1, binNumOfWindSpeed + 1):
  71. if (DzMarch809[i, 0] > (n - 1) * intervalWindspeed) and (DzMarch809[i, 0] <= n * intervalWindspeed):
  72. nWhichV = n
  73. break
  74. if (nWhichP > 0) and (nWhichV > 0):
  75. XBoxNumber[nWhichP - 1][nWhichV - 1] += 1
  76. for m in range(1,binNumOfPower+1):
  77. for n in range(1,binNumOfWindSpeed+1):
  78. XBoxNumber[m-1,n-1] = XBoxNumber[m-1,n-1] - 1
  79. return XBoxNumber
  80. def percentageDots(self,XBoxNumber, binNumOfPower, binNumOfWindSpeed,axis):
  81. BoxPercent = np.zeros((binNumOfPower, binNumOfWindSpeed), dtype=float)
  82. BinSum = np.zeros((binNumOfPower if axis == 'power' else binNumOfWindSpeed, 1), dtype=int)
  83. for i in range(1,1+(binNumOfPower if axis == 'power' else binNumOfWindSpeed)):
  84. for m in range(1,(binNumOfWindSpeed if axis == 'power' else binNumOfPower)+1):
  85. BinSum[i-1] = BinSum[i-1] + (XBoxNumber[i-1,m-1] if axis == 'power' else XBoxNumber[m-1,i-1])
  86. for m in range(1,(binNumOfWindSpeed if axis == 'power' else binNumOfPower)+1):
  87. if BinSum[i-1]>0:
  88. if axis == 'power':
  89. BoxPercent[i-1,m-1] = (XBoxNumber[i-1,m-1] / BinSum[i-1])*100
  90. else:
  91. BoxPercent[m-1,i-1] = (XBoxNumber[m-1,i-1] / BinSum[i-1])*100
  92. return BoxPercent,BinSum
  93. def maxBoxPercentage(self,BoxPercent, binNumOfPower, binNumOfWindSpeed, axis):
  94. BoxMaxIndex = np.zeros((binNumOfPower if axis == 'power' else binNumOfWindSpeed,1),dtype = int)
  95. BoxMax = np.zeros((binNumOfPower if axis == 'power' else binNumOfWindSpeed,1),dtype = float)
  96. for m in range(1,(binNumOfPower if axis == 'power' else binNumOfWindSpeed)+1):
  97. BoxMaxIndex[m-1] = (np.argmax(BoxPercent[m-1, :])) if axis == 'power' else (np.argmax(BoxPercent[:, m-1]))
  98. BoxMax[m-1] = (np.max(BoxPercent[m-1, :]))if axis == 'power' else (np.max(BoxPercent[:, m-1]))
  99. return BoxMaxIndex, BoxMax
  100. def extendBoxPercent(self,m, BoxMax,TopP,BoxMaxIndex,BoxPercent,binNumOfPower,binNumOfWindSpeed):
  101. DotDense = np.zeros(binNumOfPower)
  102. DotDenseLeftRight = np.zeros((binNumOfPower,2))
  103. DotValve = m
  104. PDotDenseSum = 0
  105. for i in range(binNumOfPower - TopP):
  106. PDotDenseSum = BoxMax[i]
  107. iSpreadRight = 1
  108. iSpreadLeft = 1
  109. while PDotDenseSum < DotValve:
  110. if (BoxMaxIndex[i] + iSpreadRight) < binNumOfWindSpeed-1-1:
  111. PDotDenseSum += BoxPercent[i, BoxMaxIndex[i] + iSpreadRight]
  112. iSpreadRight += 1
  113. else:
  114. break
  115. if (BoxMaxIndex[i] - iSpreadLeft) > 0:
  116. PDotDenseSum += BoxPercent[i, BoxMaxIndex[i] - iSpreadLeft]
  117. iSpreadLeft += 1
  118. else:
  119. break
  120. iSpreadRight = iSpreadRight-1
  121. iSpreadLeft = iSpreadLeft-1
  122. DotDenseLeftRight[i, 0] = iSpreadLeft
  123. DotDenseLeftRight[i, 1] = iSpreadRight
  124. DotDense[i] = iSpreadLeft + iSpreadRight + 1
  125. return DotDenseLeftRight
  126. def calculatePWidth(self,binNumOfPower,TopP,DotDenseLeftRight,PBinSum):
  127. PowerLimit = np.zeros(binNumOfPower, dtype=int)
  128. WidthAverage = 0
  129. WidthAverage_L = 0
  130. nCounter = 0
  131. PowerLimitValve = 6
  132. N_Pcount = 20
  133. for i in range(binNumOfPower - TopP):
  134. if (DotDenseLeftRight[i, 1] > PowerLimitValve) and (PBinSum[i] > N_Pcount):
  135. PowerLimit[i] = 1
  136. if DotDenseLeftRight[i, 1] <= PowerLimitValve:
  137. WidthAverage += DotDenseLeftRight[i, 1]
  138. WidthAverage_L += DotDenseLeftRight[i,1]
  139. nCounter += 1
  140. WidthAverage /= nCounter if nCounter > 0 else 1
  141. WidthAverage_L /= nCounter if nCounter > 0 else 1
  142. return WidthAverage, WidthAverage_L,PowerLimit
  143. def amendMaxBox(self,binNumOfPower,TopP,PowerLimit,BoxMaxIndex):
  144. end=binNumOfPower - TopP
  145. for i in range(1, binNumOfPower - TopP):
  146. if i>=end:
  147. continue
  148. if (PowerLimit[i] == 1) and (abs(BoxMaxIndex[i] - BoxMaxIndex[i - 1]) > 5):
  149. BoxMaxIndex[i] = BoxMaxIndex[i - 1] + 1
  150. return BoxMaxIndex
  151. def markBoxLimit(self,binNumOfPower,binNumOfWindSpeed,TopP,CurveWidthR,CurveWidthL,BoxMaxIndex):
  152. BBoxRemove = np.zeros((binNumOfPower, binNumOfWindSpeed), dtype=int)
  153. for m in range(binNumOfPower - TopP):
  154. for n in range(int(BoxMaxIndex[m]) + int(CurveWidthR), binNumOfWindSpeed):
  155. BBoxRemove[m, n] = 1
  156. for n in range(int(BoxMaxIndex[m]) - int(CurveWidthL)+1, 0, -1):
  157. if n-1>=binNumOfWindSpeed:
  158. continue
  159. BBoxRemove[m, n-1] = 2
  160. return BBoxRemove
  161. def markBoxPLimit(self,binNumOfPower,binNumOfWindSpeed,TopP,CurveWidthR,PowerLimit,BoxPercent,BoxMaxIndex,mm_value:int,BBoxRemove,nn_value:int):
  162. BBoxLimit = np.zeros((binNumOfPower, binNumOfWindSpeed), dtype=int)
  163. for i in range(2, binNumOfPower - TopP):
  164. if PowerLimit[i] == 1:
  165. BBoxLimit[i, int(BoxMaxIndex[i] + CurveWidthR + 1):binNumOfWindSpeed] = 1
  166. IsolateValve = 3
  167. for m in range(binNumOfPower - TopP):
  168. for n in range(int(BoxMaxIndex[m]) + int(CurveWidthR), binNumOfWindSpeed):
  169. if BoxPercent[m, n] < IsolateValve:
  170. BBoxRemove[m, n] = 1
  171. for m in range(binNumOfPower - TopP, binNumOfPower):
  172. for n in range(binNumOfWindSpeed):
  173. BBoxRemove[m, n] = 3
  174. # 标记功率主带拐点左侧的欠发网格
  175. for m in range(mm_value - 1, binNumOfPower - TopP):
  176. for n in range(int(nn_value) - 2):
  177. BBoxRemove[m, n] = 2
  178. return BBoxLimit
  179. def markData(self,binNumOfPower, binNumOfWindSpeed,DzMarch809,BBoxRemove,nCounter1):
  180. DzMarch809Sel = np.zeros(nCounter1, dtype=int)
  181. nWhichP = 0
  182. nWhichV = 0
  183. for i in range(nCounter1):
  184. for m in range( binNumOfPower ):
  185. if ((DzMarch809[i,1])> m * intervalPower) and ((DzMarch809[i,1]) <= (m+1) * intervalPower):
  186. nWhichP = m #m记录的是index
  187. break
  188. for n in range( binNumOfWindSpeed ):
  189. if DzMarch809[i,0] > ((n+1) * intervalWindspeed - intervalWindspeed/2) and DzMarch809[i,0] <= ((n+1) * intervalWindspeed + intervalWindspeed / 2):
  190. nWhichV = n
  191. break
  192. if nWhichP >= 0 and nWhichV >= 0:
  193. if BBoxRemove[nWhichP, nWhichV] == 1:
  194. DzMarch809Sel[i] = 1
  195. elif BBoxRemove[nWhichP, nWhichV] == 2:
  196. DzMarch809Sel[i] = 2
  197. elif BBoxRemove[nWhichP , nWhichV] == 3:
  198. DzMarch809Sel[i] = 0
  199. return DzMarch809Sel
  200. def windowFilter(self,nCounter1,ratedPower,DzMarch809,DzMarch809Sel,Point_line):
  201. PVLimit = np.zeros((nCounter1, 3))
  202. nLimitTotal = 0
  203. nWindowLength = 6
  204. LimitWindow = np.zeros(nWindowLength)
  205. UpLimit = 0
  206. LowLimit = 0
  207. PowerStd = 30
  208. nWindowNum = np.floor(nCounter1/nWindowLength)
  209. PowerLimitUp = ratedPower - 100
  210. PowerLimitLow = 100
  211. # 循环遍历每个窗口
  212. for i in range(int(nWindowNum)):
  213. start_idx = i * nWindowLength
  214. end_idx = start_idx + nWindowLength
  215. LimitWindow = DzMarch809[start_idx:end_idx, 1]
  216. bAllInAreas = np.all(LimitWindow >= PowerLimitLow) and np.all(LimitWindow <= PowerLimitUp)
  217. if not bAllInAreas:
  218. continue
  219. UpLimit = LimitWindow[0] + PowerStd
  220. LowLimit = LimitWindow[0] - PowerStd
  221. bAllInUpLow = np.all(LimitWindow >= LowLimit) and np.all(LimitWindow <= UpLimit)
  222. if bAllInUpLow:
  223. DzMarch809Sel[start_idx:end_idx] = 4
  224. for j in range(nWindowLength):
  225. PVLimit[nLimitTotal, :2] = DzMarch809[start_idx + j, :2]
  226. PVLimit[nLimitTotal, 2] = Point_line[start_idx + j] # 对数据进行标识
  227. nLimitTotal += 1
  228. return PVLimit,nLimitTotal
  229. def store_points(self,DzMarch809, DzMarch809Sel,Point_line, nCounter1):
  230. PVDot = np.zeros((nCounter1, 3))
  231. PVBad = np.zeros((nCounter1, 3))
  232. nCounterPV = 0
  233. nCounterBad = 0
  234. for i in range(nCounter1):
  235. if DzMarch809Sel[i] == 0:
  236. nCounterPV += 1
  237. PVDot[nCounterPV-1, :2] = DzMarch809[i, :2]
  238. PVDot[nCounterPV-1, 2] = Point_line[i]
  239. elif DzMarch809Sel[i] in [1, 2, 3]:
  240. nCounterBad += 1
  241. PVBad[nCounterBad-1, :2] = DzMarch809[i, :2]
  242. PVBad[nCounterBad-1, 2] = Point_line[i]
  243. return PVDot, nCounterPV,PVBad,nCounterBad
  244. def markAllData(self,nCounterPV,nCounterBad,dataFramePartOfSCADA,PVDot,PVBad,SM,nLimitTotal,PVLimit):
  245. for i in range(nCounterPV):
  246. dataFramePartOfSCADA[int(PVDot[i, 2] - 1), (SM[1]-1)] = 1
  247. #坏点
  248. for i in range(nCounterBad):
  249. dataFramePartOfSCADA[int(PVBad[i, 2] - 1),(SM[1]-1)] = 5 # 坏点标识
  250. # 对所有数据中的限电点进行标注
  251. for i in range(nLimitTotal):
  252. dataFramePartOfSCADA[int(PVLimit[i, 2] - 1),(SM[1]-1)] = 4 # 限电点标识
  253. return dataFramePartOfSCADA
  254. # 4. 数据可视化
  255. def plotData(self,turbineName:str,ws:list, ap:list):
  256. fig = plt.figure()
  257. plt.scatter(ws, ap, s=1, c='black', marker='.')
  258. ax = plt.gca()
  259. ax.xaxis.set_major_locator(MultipleLocator(5))
  260. ax.yaxis.set_major_locator(MultipleLocator(500))
  261. plt.title(turbineName)
  262. plt.xlim((0, 30))
  263. plt.ylim((0, 2200))
  264. plt.tick_params(labelsize=8)
  265. plt.xlabel("V/(m$·$s$^{-1}$)", fontsize=8)
  266. plt.ylabel("P/kW", fontsize=8)
  267. plt.show()
  268. def main(self,dataFrame:pd.DataFrame,ratedPower,cusInWS,cusOutWS):
  269. dataFramePartOfSCADA = self.preprocessData(dataFrame)
  270. powerMax = dataFrame[Field_ActiverPower].max()
  271. # ratedPower=dataFrame[Field_RatedPower].iloc[0]
  272. # cusInWS=dataFrame[Field_CutInWS].iloc[0]
  273. # cusOutWS=dataFrame[Field_CutOutWS].iloc[0]
  274. if pd.isna(ratedPower):
  275. raise CustomError(109)
  276. if pd.isna(cusInWS):
  277. raise CustomError(107)
  278. if pd.isna(cusOutWS):
  279. raise CustomError(107)
  280. binNumOfPower, binNumOfWindSpeed = self.calculateIntervals(powerMax,ratedPower, cusOutWS)
  281. TopP = self.calculateTopP(powerMax,ratedPower)
  282. # 根据功率阈值对数据进行标签分配
  283. DzMarch809,nCounter1,dataFramePartOfSCADA,Point_line,SM = self.chooseData(dataFramePartOfSCADA,dataFrame)
  284. XBoxNumber = self.gridCount(binNumOfWindSpeed,binNumOfPower,nCounter1,DzMarch809)
  285. PBoxPercent,PBinSum = self.percentageDots(XBoxNumber, binNumOfPower, binNumOfWindSpeed, 'power')
  286. VBoxPercent,VBinSum = self.percentageDots(XBoxNumber, binNumOfPower, binNumOfWindSpeed, 'speed')
  287. PBoxMaxIndex, PBoxMaxP = self.maxBoxPercentage(PBoxPercent, binNumOfPower, binNumOfWindSpeed, 'power')
  288. VBoxMaxIndex, VBoxMaxV = self.maxBoxPercentage(VBoxPercent, binNumOfPower, binNumOfWindSpeed, 'speed')
  289. if PBoxMaxIndex[0] > 14: PBoxMaxIndex[0] = 9
  290. DotDenseLeftRight = self.extendBoxPercent(90, PBoxMaxP,TopP,PBoxMaxIndex,PBoxPercent,binNumOfPower,binNumOfWindSpeed)
  291. WidthAverage, WidthAverage_L,PowerLimit = self.calculatePWidth(binNumOfPower,TopP,DotDenseLeftRight,PBinSum)
  292. PBoxMaxIndex = self.amendMaxBox(binNumOfPower,TopP,PowerLimit,PBoxMaxIndex)
  293. # 计算功率主带的左右边界
  294. CurveWidthR = np.ceil(WidthAverage) + 2
  295. CurveWidthL = np.ceil(WidthAverage_L) + 2
  296. #确定功率主带的左上拐点,即额定风速位置的网格索引
  297. CurveTop = np.zeros((2, 1), dtype=int)
  298. BTopFind = 0
  299. mm_value = None
  300. nn_value = None
  301. mEnd=binNumOfPower - TopP
  302. for m in range(binNumOfPower - TopP, 0, -1):
  303. if m>=mEnd:
  304. continue
  305. for n in range(int(np.floor(int(cusInWS) / intervalWindspeed)), binNumOfWindSpeed - 1):
  306. if (VBoxPercent[m, n - 1] < VBoxPercent[m, n]) and (VBoxPercent[m, n] <= VBoxPercent[m, n + 1]) and (XBoxNumber[m, n] >= 3):
  307. CurveTop[0] = m
  308. CurveTop[1] = n #[第80个,第40个]
  309. BTopFind = 1
  310. mm_value = m
  311. nn_value = n
  312. break
  313. if BTopFind == 1:
  314. break
  315. #标记网格
  316. BBoxRemove = self.markBoxLimit(binNumOfPower,binNumOfWindSpeed,TopP,CurveWidthR,CurveWidthL,PBoxMaxIndex)
  317. if mm_value is not None and nn_value is not None:
  318. BBoxLimit = self.markBoxPLimit(binNumOfPower,binNumOfWindSpeed,TopP,CurveWidthR,PowerLimit,PBoxPercent,PBoxMaxIndex,mm_value,BBoxRemove,nn_value)
  319. DzMarch809Sel = self.markData(binNumOfPower, binNumOfWindSpeed,DzMarch809,BBoxRemove,nCounter1)
  320. PVLimit,nLimitTotal = self.windowFilter(nCounter1,ratedPower,DzMarch809,DzMarch809Sel,Point_line)
  321. #将功率滑动窗口主带平滑化
  322. nSmooth = 0
  323. for i in range(binNumOfPower - TopP - 1):
  324. PVLeftDown = np.zeros(2)
  325. PVRightUp = np.zeros(2)
  326. if PBoxMaxIndex[i + 1] - PBoxMaxIndex[i] >= 1:
  327. # 计算左下和右上顶点的坐标
  328. PVLeftDown[0] = (PBoxMaxIndex[i]+1 + CurveWidthR) * 0.25 - 0.125
  329. PVLeftDown[1] = (i) * 25
  330. PVRightUp[0] = (PBoxMaxIndex[i+1]+1 + CurveWidthR) * 0.25 - 0.125
  331. PVRightUp[1] = (i+1) * 25
  332. for m in range(nCounter1):
  333. # 检查当前点是否在锯齿区域内
  334. if (DzMarch809[m, 0] > PVLeftDown[0]) and (DzMarch809[m, 0] < PVRightUp[0]) and (DzMarch809[m, 1] > PVLeftDown[1]) and (DzMarch809[m, 1] < PVRightUp[1]):
  335. # 检查斜率是否大于对角连线
  336. if ((DzMarch809[m, 1] - PVLeftDown[1]) / (DzMarch809[m, 0] - PVLeftDown[0])) > ((PVRightUp[1] - PVLeftDown[1]) / (PVRightUp[0] - PVLeftDown[0])):
  337. # 如果在锯齿左上三角形中,则选中并增加锯齿平滑计数器
  338. DzMarch809Sel[m] = 0
  339. nSmooth += 1
  340. # DzMarch809Sel 数组现在包含了锯齿平滑的选择结果,nSmooth 是选中的点数
  341. PVDot, nCounterPV,PVBad,nCounterBad = self.store_points(DzMarch809, DzMarch809Sel,Point_line, nCounter1)
  342. #标注
  343. dataFramePartOfSCADA = self.markAllData(nCounterPV,nCounterBad,dataFramePartOfSCADA,PVDot,PVBad,SM,nLimitTotal,PVLimit)
  344. A = dataFramePartOfSCADA[:,-1]
  345. A=pd.DataFrame(A,columns=[Field_LableFlag])
  346. dataFrame = pd.concat([dataFrame,A],axis=1)
  347. dataFrame[Field_LableFlag]=dataFrame[Field_LableFlag].fillna(0)
  348. """
  349. 标识 说明
  350. 5 坏点
  351. 4 限功率点
  352. 1 好点
  353. 0 null
  354. -1 P<=10
  355. """
  356. print("lab unique :",dataFrame[Field_LableFlag].unique())
  357. # data=dataFrame[dataFrame[Field_LableFlag]==1]
  358. # self.plotData(data[Field_NameOfTurbine].iloc[0],data[Field_WindSpeed],data[Field_ActiverPower])
  359. return dataFrame
  360. if __name__ == '__main__':
  361. main()