|
@@ -1,4 +1,4 @@
|
|
|
-
|
|
|
+#充电基础表单所需库
|
|
|
import datetime
|
|
|
import pandas as pd
|
|
|
import numpy as np
|
|
@@ -7,7 +7,8 @@ import math
|
|
|
from LIB.MIDDLE.CellStateEstimation.Common.V1_0_1 import BatParam
|
|
|
import requests
|
|
|
import re
|
|
|
-
|
|
|
+#预测充电环境所需库
|
|
|
+import joblib #sklearn模型的保存与加载
|
|
|
|
|
|
def process(data_ori_temp,cellvolt_list,celltemp_name,sn):
|
|
|
data_ori_temp=data_ori_temp.drop(['GSM信号','故障等级','故障代码','开关状态','绝缘电阻','定位类型','速度[km/h]','有效位','外电压','总输出状态','上锁状态','加热状态','航向'],axis=1,errors='ignore')
|
|
@@ -24,7 +25,7 @@ def process(data_ori_temp,cellvolt_list,celltemp_name,sn):
|
|
|
data_ori_delnone=data_ori_temp.fillna(method ='backfill', axis = 0)
|
|
|
if data_ori_delnone.loc[0,'经度'] is None:
|
|
|
data_ori_delnone['经度']=116.417
|
|
|
- data_ori_delnone['纬度']=39.917
|
|
|
+ data_ori_delnone['纬度']=39.917
|
|
|
data_ori_delnone = data_ori_delnone.dropna(axis = 1)
|
|
|
for name_col in cellvolt_list:
|
|
|
data_ori_delnone = data_ori_delnone.drop(data_ori_delnone[(data_ori_delnone[name_col] < 2000)].index)
|
|
@@ -36,6 +37,9 @@ def process(data_ori_temp,cellvolt_list,celltemp_name,sn):
|
|
|
def city(df_sts_chrg,gpscity):
|
|
|
listcity=[]
|
|
|
data_sta=df_sts_chrg.reset_index(drop=True)
|
|
|
+ if '经度' not in list(data_sta.columns):
|
|
|
+ data_sta['经度']=116.417
|
|
|
+ data_sta['纬度']=39.917
|
|
|
for i in range(len(data_sta)):
|
|
|
dist=[]
|
|
|
for j in range(len(gpscity)):
|
|
@@ -55,10 +59,22 @@ def gpstemp_new(data_sta):
|
|
|
headers = {
|
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36',
|
|
|
}
|
|
|
- if data_sta.loc[0,'city'][:2]=='北京':
|
|
|
- response = requests.get('http://www.weather.com.cn/html/weather/101010100.shtml',headers=headers)
|
|
|
- elif data_sta.loc[0,'city'][:2]=='苏州':
|
|
|
- response = requests.get('http://www.weather.com.cn/html/weather/101190401.shtml',headers=headers)
|
|
|
+ r = requests.get('http://www.cma.gov.cn/',headers=headers)
|
|
|
+ r.encoding = r.apparent_encoding
|
|
|
+
|
|
|
+
|
|
|
+ city = re.findall('c\[\d{,2}\] = new Array\("选择城市",(.*?)\)',r.text)
|
|
|
+ city = re.findall('"([\u4e00-\u9fa5]*?)"',str(city))
|
|
|
+ # 不存在佛山的网页
|
|
|
+ city.remove('佛山')
|
|
|
+
|
|
|
+ sign = re.findall('n\[\d{,2}\] = new Array.*?\("0",(.*?)\)',r.text,re.S)
|
|
|
+ sign = re.findall('"(\d*?)"',str(sign))
|
|
|
+
|
|
|
+ city_sign = dict(zip(city,sign))
|
|
|
+ city= data_sta.loc[0,'city'][:2]
|
|
|
+ response = requests.get('http://www.weather.com.cn/html/weather/'+city_sign[city]+'.shtml',headers=headers)
|
|
|
+
|
|
|
response.encoding = response.apparent_encoding
|
|
|
# 时间,需要反转一下,因为最后一条数据对应第一个
|
|
|
x_time = re.findall('"od21":"(.*?)"',response.text)
|
|
@@ -289,9 +305,9 @@ def chrgst_time(data_split): #重新计算前后闲置时长
|
|
|
def chrgdr(data_split): #根据充电信息结果合并相连同状态
|
|
|
chrg=pd.DataFrame()
|
|
|
if data_split.loc[0,'data_status']=='charge':
|
|
|
- chrg=chrg.append(data_split.iloc[k])
|
|
|
+ chrg=chrg.append(data_split.iloc[0])
|
|
|
|
|
|
- for k in range(1,len(data_split)-1):
|
|
|
+ for k in range(1,len(data_split)):
|
|
|
if data_split.loc[k,'data_status']=='charge':
|
|
|
if data_split.loc[k-1,'data_status']=='stand':
|
|
|
chrg=chrg.append(data_split.iloc[k-2:k+1])
|
|
@@ -315,54 +331,54 @@ def makedf_chrgdr(df_splice_chrg,data_new): #每个status取所有时间戳的
|
|
|
return df_chrg
|
|
|
|
|
|
def change_new(df_sts_chrg,chrg_last):
|
|
|
+ chrg_last=pd.DataFrame()
|
|
|
df_sts_chrg.reset_index(drop=True,inplace=True)
|
|
|
- time_last=chrg_last['time_end']
|
|
|
- time_first=df_sts_chrg.loc[0,'time_st']
|
|
|
- time_last=datetime.datetime.strptime(time_last,'%Y-%m-%d %H:%M:%S')
|
|
|
- if (chrg_last['status']==df_sts_chrg.loc[0,'status']) & ((time_first-time_last).total_seconds()/60<10) & \
|
|
|
- (round(chrg_last['gps_lat'],2)==round(df_sts_chrg.loc[0,'gps_lat'],2)) & \
|
|
|
- (round(chrg_last['gps_lon'],2)==round(df_sts_chrg.loc[0,'gps_lon'],2)) :
|
|
|
- chrg_last['time_end']=df_sts_chrg.loc[0,'time_end']
|
|
|
- chrg_last['delta_time']=chrg_last['delta_time']+df_sts_chrg.loc[0,'delta_time']
|
|
|
- chrg_last['soc_end']=df_sts_chrg.loc[0,'soc_end']
|
|
|
- chrg_last['volt_end']=df_sts_chrg.loc[0,'volt_end']
|
|
|
- chrg_last['diffvolt_end']=df_sts_chrg.loc[0,'diffvolt_end']
|
|
|
- chrg_last['temp_max']=np.max([df_sts_chrg.loc[0,'temp_max'],chrg_last['temp_max']])
|
|
|
- chrg_last['temp_min']=np.min([df_sts_chrg.loc[0,'temp_min'],chrg_last['temp_min']])
|
|
|
- chrg_last['temp_incr']=df_sts_chrg.loc[0,'temp_incr']+chrg_last['temp_incr']
|
|
|
- chrg_last['temp_mean']=round(np.mean([df_sts_chrg.loc[0,'temp_mean'],chrg_last['temp_mean']]),1)
|
|
|
- #chrg_last['temp_end_max']=df_sts_chrg.loc[0,'temp_end_max']
|
|
|
- #chrg_last['temp_end_min']=df_sts_chrg.loc[0,'temp_end_min']
|
|
|
- chrg_last['temp_end_mean']=df_sts_chrg.loc[0,'temp_end_mean']
|
|
|
- chrg_last['difftem_max']=np.max([df_sts_chrg.loc[0,'difftem_max'],chrg_last['difftem_max']])
|
|
|
- delta_soc=chrg_last['soc_end']-chrg_last['soc_st']
|
|
|
- if delta_soc >= 3:
|
|
|
- rate_chrg =round(delta_soc/(100*chrg_last['delta_time']), 2) #电流的等效倍率
|
|
|
- else:
|
|
|
- rate_chrg = 0
|
|
|
- if rate_chrg > 0.3:
|
|
|
- stat_flg = 1#快充
|
|
|
- elif rate_chrg > 0:
|
|
|
- stat_flg = 2#慢充
|
|
|
- else:
|
|
|
- stat_flg = 0
|
|
|
- if chrg_last['soc_end'] > 98:
|
|
|
- full_chg_flg = 1#满充
|
|
|
- else:
|
|
|
- full_chg_flg = 0
|
|
|
- chrg_last['meancrnt']= rate_chrg
|
|
|
- chrg_last['max_meancrnt']=np.max([df_sts_chrg.loc[0,'max_meancrnt'],chrg_last['max_meancrnt']])
|
|
|
- chrg_last['sts_flg']= stat_flg
|
|
|
- chrg_last['full_chrg_flg']= full_chg_flg
|
|
|
- chrg_last['ovchrg_flg']= np.max([df_sts_chrg.loc[0,'ovchrg_flg'],chrg_last['ovchrg_flg']])
|
|
|
- chrg_last['ovchrg_prop']=df_sts_chrg.loc[0,'ovchrg_prop']+chrg_last['ovchrg_prop']
|
|
|
- chrg_last['standtime_b']=df_sts_chrg.loc[0,'standtime_b']
|
|
|
- chrg_last['airtemp_end']=df_sts_chrg.loc[0,'airtemp_end']
|
|
|
- chrg_last=pd.DataFrame(chrg_last).T
|
|
|
- df_sts_chrg=df_sts_chrg.drop([0])
|
|
|
-
|
|
|
- else:
|
|
|
- chrg_last=pd.DataFrame()
|
|
|
+ if len(chrg_last)>0:
|
|
|
+ time_last=chrg_last['time_end']
|
|
|
+ time_first=df_sts_chrg.loc[0,'time_st']
|
|
|
+ time_last=datetime.datetime.strptime(time_last,'%Y-%m-%d %H:%M:%S')
|
|
|
+ if (chrg_last['status']==df_sts_chrg.loc[0,'status']) & ((time_first-time_last).total_seconds()/60<10) & \
|
|
|
+ (round(chrg_last['gps_lat'],2)==round(df_sts_chrg.loc[0,'gps_lat'],2)) & \
|
|
|
+ (round(chrg_last['gps_lon'],2)==round(df_sts_chrg.loc[0,'gps_lon'],2)) :
|
|
|
+ chrg_last['time_end']=df_sts_chrg.loc[0,'time_end']
|
|
|
+ chrg_last['delta_time']=chrg_last['delta_time']+df_sts_chrg.loc[0,'delta_time']
|
|
|
+ chrg_last['soc_end']=df_sts_chrg.loc[0,'soc_end']
|
|
|
+ chrg_last['volt_end']=df_sts_chrg.loc[0,'volt_end']
|
|
|
+ chrg_last['diffvolt_end']=df_sts_chrg.loc[0,'diffvolt_end']
|
|
|
+ chrg_last['temp_max']=np.max([df_sts_chrg.loc[0,'temp_max'],chrg_last['temp_max']])
|
|
|
+ chrg_last['temp_min']=np.min([df_sts_chrg.loc[0,'temp_min'],chrg_last['temp_min']])
|
|
|
+ chrg_last['temp_incr']=df_sts_chrg.loc[0,'temp_incr']+chrg_last['temp_incr']
|
|
|
+ chrg_last['temp_mean']=round(np.mean([df_sts_chrg.loc[0,'temp_mean'],chrg_last['temp_mean']]),1)
|
|
|
+ #chrg_last['temp_end_max']=df_sts_chrg.loc[0,'temp_end_max']
|
|
|
+ #chrg_last['temp_end_min']=df_sts_chrg.loc[0,'temp_end_min']
|
|
|
+ chrg_last['temp_end_mean']=df_sts_chrg.loc[0,'temp_end_mean']
|
|
|
+ chrg_last['difftem_max']=np.max([df_sts_chrg.loc[0,'difftem_max'],chrg_last['difftem_max']])
|
|
|
+ delta_soc=chrg_last['soc_end']-chrg_last['soc_st']
|
|
|
+ if delta_soc >= 3:
|
|
|
+ rate_chrg =round(delta_soc/(100*chrg_last['delta_time']), 2) #电流的等效倍率
|
|
|
+ else:
|
|
|
+ rate_chrg = 0
|
|
|
+ if rate_chrg > 0.3:
|
|
|
+ stat_flg = 1#快充
|
|
|
+ elif rate_chrg > 0:
|
|
|
+ stat_flg = 2#慢充
|
|
|
+ else:
|
|
|
+ stat_flg = 0
|
|
|
+ if chrg_last['soc_end'] > 98:
|
|
|
+ full_chg_flg = 1#满充
|
|
|
+ else:
|
|
|
+ full_chg_flg = 0
|
|
|
+ chrg_last['meancrnt']= rate_chrg
|
|
|
+ chrg_last['max_meancrnt']=np.max([df_sts_chrg.loc[0,'max_meancrnt'],chrg_last['max_meancrnt']])
|
|
|
+ chrg_last['sts_flg']= stat_flg
|
|
|
+ chrg_last['full_chrg_flg']= full_chg_flg
|
|
|
+ chrg_last['ovchrg_flg']= np.max([df_sts_chrg.loc[0,'ovchrg_flg'],chrg_last['ovchrg_flg']])
|
|
|
+ chrg_last['ovchrg_prop']=df_sts_chrg.loc[0,'ovchrg_prop']+chrg_last['ovchrg_prop']
|
|
|
+ chrg_last['standtime_b']=df_sts_chrg.loc[0,'standtime_b']
|
|
|
+ chrg_last['airtemp_end']=df_sts_chrg.loc[0,'airtemp_end']
|
|
|
+ chrg_last=pd.DataFrame(chrg_last).T
|
|
|
+ df_sts_chrg=df_sts_chrg.drop([0])
|
|
|
+
|
|
|
return df_sts_chrg,chrg_last
|
|
|
|
|
|
def sep_chrg_dr(df_merge,sn,gpscity):
|
|
@@ -370,21 +386,22 @@ def sep_chrg_dr(df_merge,sn,gpscity):
|
|
|
celltemp_name = [s for s in list(df_merge) if '温度' in s]
|
|
|
df_data=process(df_merge,cellvolt_list,celltemp_name,sn)
|
|
|
celltype=defcelltype(sn)
|
|
|
- param=BatParam.BatParam(celltype)
|
|
|
- df_data['总电流[A]']=param.PackCrntDec*df_data['总电流[A]']
|
|
|
- data_new=DataPreProcess.data_split_by_status(df_data,df_data)
|
|
|
- data_new=DataPreProcess.data_split_by_time(data_new,data_new)
|
|
|
- data_new=DataPreProcess.cal_stand_time(data_new,data_new)
|
|
|
- data_new.reset_index(inplace = True, drop = True)
|
|
|
- data_sta=city(data_new,gpscity)
|
|
|
- data_sta=data_sta.reset_index(drop=True)
|
|
|
- data_sta2=gpstemp_new(data_sta)
|
|
|
- data_sta2.to_csv('data_sta2.csv')
|
|
|
- data_split=newsplit(data_sta2)
|
|
|
- data_split.to_csv('data_split.csv')
|
|
|
- data_split=chrgst_time(data_split)
|
|
|
-
|
|
|
- chrg=chrgdr(data_split)
|
|
|
+ param=BatParam.BatParam(celltype)
|
|
|
+ chrg=pd.DataFrame()
|
|
|
+ data_sta2=pd.DataFrame()
|
|
|
+ if len(df_data)>0:
|
|
|
+ df_data['总电流[A]']=param.PackCrntDec*df_data['总电流[A]']
|
|
|
+ data_new=DataPreProcess.data_split_by_status(df_data,df_data)
|
|
|
+ data_new=DataPreProcess.data_split_by_time(data_new,data_new)
|
|
|
+ data_new=DataPreProcess.cal_stand_time(data_new,data_new)
|
|
|
+ data_new.reset_index(inplace = True, drop = True)
|
|
|
+ data_sta=city(data_new,gpscity)
|
|
|
+ data_sta=data_sta.reset_index(drop=True)
|
|
|
+ data_sta2=gpstemp_new(data_sta)
|
|
|
+ data_split=newsplit(data_sta2)
|
|
|
+ data_split=chrgst_time(data_split)
|
|
|
+ if len(data_split)>0:
|
|
|
+ chrg=chrgdr(data_split)
|
|
|
return chrg,data_sta2,param
|
|
|
|
|
|
def mkdf_chrg(chrg,data_new,param):
|
|
@@ -394,7 +411,7 @@ def mkdf_chrg(chrg,data_new,param):
|
|
|
df_splice_chrg = chrg[chrg['data_split_by_status_time'] == item]
|
|
|
df_splice_chrg.reset_index(inplace = True, drop = True)
|
|
|
df_chrg=makedf_chrgdr(df_splice_chrg,data_new)
|
|
|
-
|
|
|
+
|
|
|
df_sts_chrg_temp=stat_chrg_st(df_chrg,param)
|
|
|
|
|
|
if df_splice_chrg.loc[0,'data_status'] =='charge':
|
|
@@ -413,11 +430,60 @@ def pro_output(df_merge,sn,gpscity,chrg_last):
|
|
|
change=pd.DataFrame()
|
|
|
if len(df_merge)>0:
|
|
|
chrg,data_new,param=sep_chrg_dr(df_merge,sn,gpscity)
|
|
|
- chrg.to_csv('chrg.csv')
|
|
|
if len(chrg)>0:
|
|
|
data_sta=mkdf_chrg(chrg, data_new,param)
|
|
|
- data_sta.to_csv('data_sta.csv')
|
|
|
new=data_sta.copy()
|
|
|
- if len(chrg_last)>0:
|
|
|
- new,change=change_new(data_sta,chrg_last)
|
|
|
+ new,change=change_new(data_sta,chrg_last)
|
|
|
return new,change
|
|
|
+
|
|
|
+############################ Test ##########################
|
|
|
+def prediction(datatest,kmeans1,kmeans2,kmeans3):
|
|
|
+ if len(datatest)>0:
|
|
|
+ datatest.reset_index(drop=True,inplace=True)
|
|
|
+ #筛选充电数据
|
|
|
+ datatest2=datatest[datatest['status']=='charge']
|
|
|
+ #转化静置时长
|
|
|
+ X00t=datatest2[datatest2['standtime_f']>=10]
|
|
|
+ X00t['standtime_f']=10
|
|
|
+ X01t=datatest2[datatest2['standtime_f']<10]
|
|
|
+ Xt=pd.concat([X00t,X01t])
|
|
|
+ #按温度切分数据
|
|
|
+ Xt1=Xt[Xt['airtemp_st']>=18]
|
|
|
+ Xt2=Xt[Xt['airtemp_st']<18]
|
|
|
+ #温暖天气模型预测
|
|
|
+ if len(Xt1)>0:
|
|
|
+ #KMeans1
|
|
|
+ Xt11=Xt1[['standtime_f','temp_incr']]
|
|
|
+ y_hat = kmeans1.predict(np.array(Xt11))
|
|
|
+ Xt11['cluster_db']=y_hat
|
|
|
+ Xt121=Xt11[(Xt11['cluster_db']==0)|(Xt11['cluster_db']==1)]
|
|
|
+ Xt121['charge_env']='室外'
|
|
|
+ datatest=pd.merge(Xt121['charge_env'],datatest,how='outer',right_index=True,left_index=True)
|
|
|
+ #KMeans2
|
|
|
+ Xt12=Xt11[(Xt11['cluster_db']==2)|(Xt11['cluster_db']==3)]
|
|
|
+ if len(Xt12)>0:
|
|
|
+ Xt13=pd.merge(Xt12['cluster_db'],Xt1,how='left',right_index=True,left_index=True)
|
|
|
+ Xt13['airtemp']=list(Xt13[['airtemp_st','airtemp_end']].mean(axis=1))
|
|
|
+ Xt14=Xt13[['temp_max','airtemp']]
|
|
|
+ y_hat2 = kmeans2.predict(np.array(Xt14))
|
|
|
+ Xt14['cluster_db']=y_hat2
|
|
|
+ Xt151=Xt14[(Xt14['cluster_db']==1)|(Xt14['cluster_db']==2)]
|
|
|
+ for k in list(Xt151.index):
|
|
|
+ datatest.loc[k,'charge_env']='室外'
|
|
|
+ #KMeans3
|
|
|
+ Xt15=Xt14[(Xt14['cluster_db']==0)|(Xt14['cluster_db']==3)]
|
|
|
+ if len(Xt15)>0:
|
|
|
+ Xt16=pd.merge(Xt15['cluster_db'],Xt1,how='left',right_index=True,left_index=True)
|
|
|
+ Xt17=Xt16[['standtime_f','delta_time']]
|
|
|
+ y_hat3 = kmeans3.predict(np.array(Xt17))
|
|
|
+ Xt17['cluster_db']=y_hat3
|
|
|
+ Xt181=Xt17[(Xt17['cluster_db']==0)|(Xt14['cluster_db']==2)]
|
|
|
+ for k in list(Xt181.index):
|
|
|
+ datatest.loc[k,'charge_env']='室外'
|
|
|
+ Xt180=Xt17[Xt17['cluster_db']==3]
|
|
|
+ for k in list(Xt180.index):
|
|
|
+ datatest.loc[k,'charge_env']='室内'
|
|
|
+ Xt182=Xt17[Xt17['cluster_db']==1]
|
|
|
+ for k in list(Xt182.index):
|
|
|
+ datatest.loc[k,'charge_env']='疑似室内'
|
|
|
+ return datatest
|