import pandas as pd import numpy as np import time, datetime class cell_statistic: def __init__(self, df_algo_pack_param, df_bms): #参数初始化 self.sn = df_bms['sn'].iloc[0] self.df_bms=pd.DataFrame(df_bms) self.bmstime= pd.to_datetime(df_bms['time'], format='%Y-%m-%d %H:%M:%S') self.CellVoltNums = int(df_algo_pack_param['CellVoltTotalCount']) self.CellTempNums = int(df_algo_pack_param['CellTempTotalCount']) self.cellvolt_list=['cell_voltage'+str(x) for x in range(1,self.CellVoltNums+1)] self.celltemp_name=['cell_temp'+str(x) for x in range(1,self.CellTempNums+1)] self.capty = 2*float(int(df_algo_pack_param['capacity'])) #.............................................静置行为统计............................................................................ def rest_sta(self): def clean_dead_value(series, num_dead_thresh): slide_list = [series.index[0]] slide_list_all = [] for i in range(series.index[0],series.index[-1]): j = i + 1 diff = series[j] - series[i] if diff == 0: slide_list.append(j) else: slide_list.clear() slide_list.append(j) if len(slide_list) >= num_dead_thresh: target_list = slide_list.copy() slide_list_all.append(target_list) index= [] # 将找到的满足条件的index合并 for i in range(len(slide_list_all) - 1): if set(slide_list_all[i]) < set(slide_list_all[i + 1]): index.append(i) m = {i: element for i, element in enumerate(slide_list_all)} [m.pop(i) for i in index] return list(m.values()) df_data = self.df_bms.copy() df_data['crnt_flg'] = 0 df_data.loc[df_data['pack_crnt'] > 0, 'crnt_flg'] = 1 df_data.loc[df_data['pack_crnt'] < -15, 'crnt_flg'] = -1 df_data['sts_flg'] = 2 df_sts_chrg = pd.DataFrame(columns=list(df_data.columns)) df_crnt_flg = df_data['crnt_flg'] num_dead_thresh = 15#判断连续多少个数据为阈值 indexs_to_delelte = clean_dead_value(df_crnt_flg, num_dead_thresh)#获得连续数据所在的行 rest_num = len(indexs_to_delelte) if rest_num > 0:#仅有一个连续数据时 for splice_item in range(0, rest_num):#rest_num df_data_temp = df_data.iloc[indexs_to_delelte[splice_item][0]:indexs_to_delelte[splice_item][-1]]#获得电流连续数据 df_data_temp.reset_index(drop = True, inplace = True) df_soc_temp = df_data_temp['pack_soc'] delta_soc = round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3) df_time_temp = pd.to_datetime(df_data_temp['time']) delta_time = (df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours') if all(df_data_temp['crnt_flg'] == 0):#静置判断 if delta_time > 0.17: df_data_temp['sts_flg'] = 0 df_sts_chrg = df_sts_chrg.append(df_data_temp) df_sts_chrg.reset_index(drop = True, inplace = True) elif all(df_data_temp['crnt_flg'] == -1) and (delta_soc > 30) and (delta_soc < 100):#充电判断 df_data_temp['sts_flg'] = 1 df_sts_chrg = df_sts_chrg.append(df_data_temp) df_sts_chrg.reset_index(drop = True, inplace = True) elif all(df_data_temp['crnt_flg'] == 1) and (delta_soc > 30) and (delta_soc < 100):#充电判断 df_data_temp['sts_flg'] = 1 df_sts_chrg = df_sts_chrg.append(df_data_temp) df_sts_chrg.reset_index(drop = True, inplace = True) df_dschrg = pd.concat([df_data, df_sts_chrg, df_sts_chrg]).drop_duplicates(subset = ['time', 'pack_soc'], keep = False) data_temp = pd.concat([df_dschrg, df_sts_chrg]) data_temp.sort_values(by = 'time', inplace = True) data_temp.reset_index(drop = True, inplace = True) start_time = time.time() chrgrststs_clumns = ['sn', 'time_st', 'time_end', 'delta_time','soc_st', 'soc_sp', 'delta_soc', 'odo_st', 'odo_sp', 'delta_odo','chrgah', 'equchrgah','gps_lon','gps_lat','meancrnt', 'sts_flg', 'full_chrg_flg', 'crnt_aray', 'soc_aray', 'celtemmax', 'celtemmin', 'celvltmax', 'timelst', 'chrgahlst', "packvlt"] df_sts_chrg_rlt = pd.DataFrame(columns = chrgrststs_clumns)#充电与静置 if len(data_temp) > 30: #---------------------------------充电过程判断-------------------------------------- df_chrg_temp = data_temp.loc[(data_temp['sts_flg'] == 1)] if not df_chrg_temp.empty: df_chrg_temp.reset_index(inplace = True, drop = True) chrgr_time = pd.to_datetime(df_chrg_temp['time']) delta_time = (np.diff(chrgr_time)/pd.Timedelta(1, 'min'))#计算时间差的分钟数 pos = np.where(delta_time > 10)#充电数据分段,大于10min时,认为是两个充电过程 splice_num = [] if len(pos[0]) >= 1: pos_ful_tem = np.insert(pos, 0, 0) pos_len = len(pos_ful_tem) data_len = len(chrgr_time) pos_ful = np.insert(pos_ful_tem, pos_len, data_len-1) for item in range(0,len(pos_ful)-1): splice_num.extend(item*np.ones(pos_ful[item +1]-pos_ful[item])) splice_num = np.insert(splice_num, 0, 0) else: splice_num = np.zeros(len(chrgr_time)) pos_ful = np.array([0]) if len(splice_num) > 0: df_chrg_temp['chrgr_rest'] = splice_num chrgr_splice_num = np.unique(df_chrg_temp['chrgr_rest'])#判断有几段充电数据 if len(chrgr_splice_num) > 0: for item_chrgr in chrgr_splice_num: df_chrgr_splice_temp_chs = df_chrg_temp.loc[df_chrg_temp['chrgr_rest'] == item_chrgr] df_chrgr_splice_temp_chs.reset_index(inplace = True, drop = True) df_chrgr_splice_temp = df_chrgr_splice_temp_chs[(df_chrgr_splice_temp_chs[self.cellvolt_list] > 2).all(axis = 1) & (df_chrgr_splice_temp_chs[self.cellvolt_list] < 5).all(axis = 1)] df_chrgr_splice_temp.reset_index(drop = True, inplace = True) if len(df_chrgr_splice_temp) > 10: df_tem = df_chrgr_splice_temp[self.celltemp_name] celltemmax = df_tem.max(axis = 1)#每一时刻内阻最大温度 celltemmin = df_tem.min(axis = 1)#每一时刻内阻最大温度 df_celvlt = df_chrgr_splice_temp[self.cellvolt_list] cellvltmax = df_celvlt.max(axis = 1) # df_clslst = df_celvlt.tail(1) # valueset = np.sort(df_clslst.iloc[0].unique()) # valuesort = [i for i in valueset if (i > 2) and (i < 5)] # if len(valuesort) >= 3: # maxclt = valuesort[-1] # secmaxcle = valuesort[-2] # thrdmaxcle = valuesort[-3] # else: # maxclt = valuesort[-1] # secmaxcle = valuesort[-1] # thrdmaxcle = valuesort[-1] # maxcell = df_clslst.columns[df_clslst.loc[len(df_celvlt) - 1].isin([maxclt])] # seccell = df_clslst.columns[df_clslst.loc[len(df_celvlt) - 1].isin([secmaxcle])] # thrdcell = df_clslst.columns[df_clslst.loc[len(df_celvlt) - 1].isin([thrdmaxcle])] # df_cellvlt_max = df_celvlt[maxcell[0]] # df_cellvlt_secmax = df_celvlt[seccell[0]] # df_cellvlt_thrdmax = df_celvlt[thrdcell[0]] df_cellvlt = pd.concat([cellvltmax, celltemmax, celltemmin], axis = 1) df_cellvlt.columns = ['maxvlt', 'maxtem', 'mintem'] df_data_tem = df_chrgr_splice_temp[['time','sn', 'pack_crnt','pack_volt','pack_soc', 'mileage','longitude', 'latitude']] df_chrgr_splice_data = pd.concat([df_data_tem, df_tem, df_cellvlt], axis = 1) df_time_temp = pd.to_datetime(df_chrgr_splice_data['time']) df_soc_temp = df_chrgr_splice_data['pack_soc'] df_crnt = df_chrgr_splice_data['pack_crnt'] df_odo = df_chrgr_splice_data['mileage'] df_maxvlt = df_chrgr_splice_data['maxvlt'] delta_soc = round((df_soc_temp.iloc[-1] - df_soc_temp.iloc[0]), 3) delta_odo = round((df_odo.iloc[-1] - df_odo.iloc[0]), 3) np_equah = round(delta_soc*self.capty/100, 3) delta_time = round((df_time_temp.iloc[-1] - df_time_temp.iloc[0])/pd.Timedelta(1, 'hours'), 3) if (delta_soc >= 3) and (df_soc_temp.iloc[0] < 45) and (df_soc_temp.iloc[-1] > 97) and (df_maxvlt.iloc[-1] > 3.5): socnum = df_soc_temp.value_counts() #统计电芯数量这一列每个元素出现的个数 socmax = socnum.idxmax() df_datacal = df_chrgr_splice_data.loc[df_chrgr_splice_data['pack_soc'] == socmax] df_datacal.reset_index(drop = True, inplace = True) np_dff_timetp = np.diff(pd.to_datetime(df_datacal['time']))/pd.Timedelta(1, 'hours') np_dff_time_newtp = np.append(np_dff_timetp, 0) np_chrg_ahtp = np.multiply(np.array(np_dff_time_newtp),np.array(df_datacal['pack_crnt'])) chrg_ahtp = np_chrg_ahtp.sum() chrgsoc = 100*chrg_ahtp/self.capty np_dffsoc = abs(np.diff(df_soc_temp)) if all(np_dffsoc < 3) and (abs(chrgsoc)<2.5): rate_chrg = round(delta_soc/(100*delta_time), 2) np_dff_time = np.diff(df_time_temp)/pd.Timedelta(1, 'hours') np_dff_time_new = np.append(np_dff_time, 0) np_chrg_ah = np.multiply(np.array(np_dff_time_new),np.array(df_crnt)) chrg_ah = np_chrg_ah.sum() chrg_ahlst = [] for ah_k in range(1, len(np_chrg_ah)+1): chrg_ahlst.append(abs(round(np.sum(np_chrg_ah[:ah_k]), 3))) if rate_chrg > 0.001: stat_flg = 1#快充 else: stat_flg = 2#慢充 if df_soc_temp.iloc[-1] >= 98: full_chg_flg = 1#满充 else: full_chg_flg = 0 if stat_flg == 1: soc_st = int(df_soc_temp.iloc[0]) soc_sp = int(df_soc_temp.iloc[-1]) poslst = range(0, len(df_soc_temp), 1) df_chse_data = df_chrgr_splice_data.iloc[poslst] chrgahlst=chrg_ahlst[::1] crnt_ary=list(df_chse_data['pack_crnt']) soc_ary=list(df_chse_data['pack_soc']) cell_tem_max=list(df_chse_data['maxtem']) cell_tem_min=list(df_chse_data['mintem']) maxvlt=list(df_chse_data['maxvlt']) # secvlt=list(df_chse_data['secmaxvlt']) # thrdvlt=list(df_chse_data['thrdmaxvlt']) timearary=list(df_chse_data['time'].dt.strftime("%Y-%m-%d %H:%M:%S")) crntlst = [round(i,4) for i in crnt_ary] pack_vlt = list(df_chse_data['pack_volt']) df_sts_chrg_temp = pd.DataFrame({"sn":[self.sn], "time_st":[df_time_temp.iloc[0].strftime('%Y-%m-%d %H:%M:%S')], "time_end":[df_time_temp.iloc[-1]], "delta_time":[delta_time], "soc_st":[soc_st], "soc_sp":[soc_sp], "delta_soc":[delta_soc], "odo_st":[df_odo.iloc[0]], "odo_sp":[df_odo.iloc[-1]], "delta_odo":[delta_odo], "chrgah":[chrg_ah], "equchrgah":[np_equah], "gps_lon":[df_chrgr_splice_data.loc[0, 'longitude']], "gps_lat":[df_chrgr_splice_data.loc[0, 'latitude']], "meancrnt":[rate_chrg], "sts_flg":[stat_flg], "full_chrg_flg":[full_chg_flg], "crnt_aray":[str(crntlst)], "soc_aray":[str(soc_ary)],"celtemmax":[str(cell_tem_max)], "celtemmin":[str(cell_tem_min)], "celvltmax":[str(maxvlt)], "timelst":[str(timearary)], "chrgahlst":[str(chrgahlst)], "packvlt":[str(pack_vlt)]}) df_sts_chrg_rlt = df_sts_chrg_rlt.append(df_sts_chrg_temp) df_sts_chrg_rlt.reset_index(drop = True, inplace = True) df_sts_chrg_rt = df_sts_chrg_rlt.copy() df_sts_chrg_rt.sort_values(by = ['time_st'], axis = 0, ascending=True, inplace=True)#对故障信息按照时间进行排序 end_time = time.time() if not df_sts_chrg_rt.empty: return df_sts_chrg_rt else: return pd.DataFrame()