123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # time: 2023/11/21 13:33
- # file: validate.py
- # author: David
- # company: shenyang JY
- import numpy as np
- import pandas as pd
- from cache.data_cleaning import key_field_row_cleaning
- from data_process import DataProcess
- from cache.limited_power import LimitPower
- class ValidationError(Exception):
- def __init__(self, message):
- self.msg = message
- class Validation(object):
- def __init__(self, log, args):
- self.logger = log
- self.args = args
- self.opt = args.parse_args_and_yaml()
- self.status = 1
- self.process = DataProcess(log, args)
- self.lp = LimitPower(log, args, None)
- def validate_nwp(self, nwp):
- # 0. 关键字段是否缺失
- nwp_cs = [x for x in nwp.columns.to_list() if x in self.opt.nwp_columns]
- if 'C_TIME' in nwp_cs:
- nwp_cs.pop(nwp_cs.index('C_TIME'))
- nwp_filter = key_field_row_cleaning(nwp, nwp_cs, self.logger)
- if len(nwp_filter) < 8:
- self.status = 2
- raise ValidationError("NWP数据缺失")
- nwp_filter['C_TIME'] = pd.to_datetime(nwp_filter['C_TIME'])
- return nwp_filter
- def validate_his_data(self, history_rp, env, history_dq):
- if len(history_rp) <= 1 and len(env) <= 1:
- self.status = 3
- raise ValidationError("鉴权失败-历史数据时刻不满足USTA_HISTORY个数")
- if len(history_dq) < self.opt.Model["his_points"]:
- self.status = 2
- raise ValidationError("history_dq缺失")
- his = pd.merge(history_rp, history_dq, on='C_TIME')
- his = pd.merge(env, his, on='C_TIME')
- if self.opt.usable_power['clean_power_which'] in range(1, 3):
- his_clean = key_field_row_cleaning(his, [self.opt.usable_power['env']], self.logger)
- else:
- his_clean = his
- his_clean = his_clean.replace(-99, np.nan)
- points = self.opt.Model['his_points']
- if len(his_clean) < points * 0.5:
- self.status = 2
- raise ValidationError("历史数据缺失,实际长度:{}".format(len(his_clean)))
- elif len(his_clean) < self.opt.Model["his_points"] or his_clean.isnull().any().any():
- his_clean.drop(columns=['C_FP_VALUE'], inplace=True)
- his = pd.merge(history_dq, his_clean, on='C_TIME', how='left')
- his.set_index('C_TIME', inplace=True)
- his = his.interpolate(method='linear')
- his = his.fillna(method='ffill')
- his = his.fillna(method='bfill')
- his.reset_index(drop=False, inplace=True)
- his['LIMIT_STATUS'] = np.where((his['LIMIT_STATUS'] != 0) & (his['LIMIT_STATUS'] != 1), 1, his['LIMIT_STATUS'])
- return his
- else:
- return his_clean
- def validate_authentic(self, nwp, his):
- # 验证当前天气是否经过鉴权,第一个点一定要是当天的
- predict_dt = nwp.iloc[0, :]["C_TIME"]
- history_dt = his.iloc[-1, :]["C_TIME"]
- if predict_dt - history_dt > pd.Timedelta(hours=4):
- self.status = 3
- raise ValidationError("鉴权失败-环境数据结束时间早于预测开始时间4小时")
- def validate_power(self, his):
- history_rp_env = his.copy()
- new_rp = []
- for index, row in history_rp_env.iterrows():
- zfs = row[self.opt.usable_power["env"]]
- rp = row['C_REAL_VALUE']
- able_rp = row['C_ABLE_VALUE']
- status = row['LIMIT_STATUS']
- # 以下三种情况用可用功率替代:
- # 1. api_able_power可用功率参数置为True
- # 2. 取消模型融合,解析接口数据填充
- # 3. 用样板机法或单独信号法清洗限电
- if self.opt.usable_power['api_able_power'] is True or self.opt.Model['fusion'] is False or self.opt.usable_power['clean_power_which'] not in range(1, 3):
- new_rp.append(able_rp)
- # 否则用测光法和限电信号联合判断,任意一种限电就执行
- elif not self.lp.filter_unlimited_power(zfs, rp, self.opt.usable_power['k'], self.opt.usable_power['bias']) or status: # 任意判断限电
- new_rp.append(able_rp)
- else:
- new_rp.append(rp) # 全部为不限电
- history_rp_env["NEW_RP"] = new_rp
- return history_rp_env[['C_TIME', 'NEW_RP']]
|