123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- from ctypes import Structure
- from re import M
- import pandas as pd
- import numpy as np
- import datetime
- import time, datetime
- import matplotlib.pyplot as plt
- from pylab import*
- from scipy.signal import savgol_filter
- import os
- import log
- path = r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\原始数据'
-
- def get_file(): #创建一个空列表
- files =os.listdir(path)
- files.sort() #排序
- file_list= []
- for file in files:
- if not os.path.isdir(path +file): #判断该文件是否是一个文件夹
- f_name = str(file)
- # print(f_name)
- tr = '\\' #多增加一个斜杠
- filename = path + tr + f_name
- file_list.append(filename)
- return file_list
- mylog=log.Mylog('log_diag.txt','error')
- mylog.logcfg()
- file_list = get_file()
- for file in file_list:
- data = pd.read_csv(file,encoding='GB18030')
- #----------------------------------------定义滤波函数-----------------------------------------------------------------------
- def moving_average(interval, windowsize):
- window = np.ones(int(windowsize)) / float(windowsize)
- re = np.convolve(interval, window, 'same')
- return re
- #----------------------------------------区分充放电数据----------------------------------------------------------------------
- df_soc = data['SOC[%]']
- df_soc_len = len(df_soc)
- df_soc_add = df_soc.iloc[df_soc_len-3:df_soc_len-1]#由于对SOC二次微分,需要增加两行数据
- df_soc_new = df_soc.append(df_soc_add)
- df_soc_new_dif = np.diff(df_soc_new,axis=0)#电压一次微分,判断升降
- df_soc_new_dif = pd.DataFrame(df_soc_new_dif)
- df_soc_new_dif[df_soc_new_dif >= 0] = 1#SOC升高或静置
- df_soc_new_dif[df_soc_new_dif < 0] = -1#SOC下降
- df_soc_new_difdif = np.diff(df_soc_new_dif,axis=0)#三次微分,利用-2,2判断充电-静置与放电-静置的区别
- df_soc_new_difdif = pd.DataFrame(df_soc_new_difdif)
- peak_pos = np.where(df_soc_new_difdif == -2)
- bot_pos = np.where(df_soc_new_difdif == 2)
-
-
- chrgr_rest_data_temp = data.loc[((data['充电状态'] == 0) & (data['SOC[%]'] > 98) & (data['总电流[A]'] == 0))|
- ((data['充电状态'] == 2) & (data['SOC[%]'] > 98) & (data['总电流[A]'] == 0))]#接近慢充后静置数据
- chrgr_rest_data = chrgr_rest_data_temp.reset_index(drop=True)
- temp_rest_time = chrgr_rest_data['时间戳'].reset_index(drop=True)
- rest_time = pd.to_datetime(temp_rest_time)
- # rest_chrg_time = datetime(rest_time)
- # delta_time = np.diff(rest_chrg_time)
- delta_time = (np.diff(rest_time)/pd.Timedelta(1, 'min'))#计算时间差的分钟数
- pos = np.where(delta_time > 30)
- pos_ful_tem = np.insert(pos, 0, 0)
- pos_len = len(pos_ful_tem)
- data_len = len(rest_time)
- pos_ful = np.insert(pos_ful_tem, pos_len, data_len-1)
- splice_num = []
- if len(pos[0]) >= 1:
- pos_ful_tem = np.insert(pos, 0, 0)
- pos_len = len(pos_ful_tem)
- data_len = len(rest_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(temp_rest_time))
- pos_ful = np.array([0])
- chrgr_rest_data['chrgr_rest'] = splice_num
- #---------------------------判断数据点数大于30的数据段,对电压微分并画图--------------------------------------------
- cellvolt_name=['单体电压'+str(x) for x in range(1,21)]
- cellvolt_list = cellvolt_name
- chrgr_rest_check_data = chrgr_rest_data.drop(['GSM信号','故障等级','故障代码','单体压差','绝缘电阻','总电流[A]','总电压[V]','充电状态','单体压差','SOC[%]'],axis=1,inplace=False)
- chrgr_rest_check_data.fillna(value=0)
- df_rest_volt_diffdt = pd.DataFrame()
- df_rest_volt_smooth = pd.DataFrame()
- df_ini_volt_total = pd.DataFrame()
- k = 0
- for j in range(0,len(pos_ful)-1):#len(pos_ful)-1#有几段充电后静置数据
- df_test_rest_data = chrgr_rest_check_data.loc[chrgr_rest_check_data['chrgr_rest'] == j]
- df_rest_volt_smooth = pd.DataFrame()
- df_ini_volt = pd.DataFrame()
- df_test_rest_time = pd.to_datetime(df_test_rest_data['时间戳'],format='%Y-%m-%d %H:%M:%S')
- df_test_rest_time = df_test_rest_time.reset_index(drop=True)
- df_data_length = len(df_test_rest_time)
- if (df_data_length > 30) & ((df_test_rest_time[df_data_length - 1] - df_test_rest_time[0])/pd.Timedelta(1, 'min') > 40):#静置时间大于40min
- df_test_rest_time_dif_temp = np.diff(df_test_rest_time)/pd.Timedelta(1, 'min')
- num_list = []
- data_jump_pos = np.where(df_test_rest_time_dif_temp > 3)
- if len(data_jump_pos[0]) > 0:
- if data_jump_pos[0][0] > 100:
- for i in range(0,data_jump_pos[0][0],15):##采样密集时每隔10行取数据
- num_list.append(i)
- df_rest_data_temp = df_test_rest_data.iloc[num_list]
- df_test_rest_data_choose = pd.DataFrame(df_rest_data_temp)
- df_test_rest_data_choose_else = df_test_rest_data.iloc[data_jump_pos[0][0]+1:len(df_test_rest_data)-1]
- df_rest_data_recon_temp = df_test_rest_data_choose.append(df_test_rest_data_choose_else)
- df_rest_data_recon =df_rest_data_recon_temp.reset_index(drop=True)
- else:
- df_rest_data_recon = df_test_rest_data
- else:
- df_rest_data_recon = df_test_rest_data
- df_rest_time = pd.to_datetime(df_rest_data_recon['时间戳'],format='%Y-%m-%d %H:%M:%S')
- df_rest_time = df_rest_time.reset_index(drop=True)
- df_rest_time_dif_temp = np.diff(df_rest_time)/pd.Timedelta(1, 'min')
- df_rest_volt = df_rest_data_recon[cellvolt_list]
- for item in cellvolt_list:
- window_temp = int(len(df_rest_volt[item])/3)
- if window_temp%2:#滤波函数的窗口长度需为奇数
- window = window_temp
- else:
- window = window_temp - 1
- step = min(int(window/3),5)
- df_volt_smooth = savgol_filter(df_rest_volt[item],window,step)
- df_rest_volt_smooth[item] = df_volt_smooth
- df_ini_volt = df_ini_volt.append(df_rest_volt_smooth)
- df_ini_volt.columns = cellvolt_list
- df_test_rest_volt_diff_temp = np.diff(df_rest_volt_smooth,axis=0)
- df_test_rest_time_dif = pd.DataFrame(df_rest_time_dif_temp)
- df_test_rest_volt_diff = pd.DataFrame(df_test_rest_volt_diff_temp)
- df_test_rest_volt_diffdt_temp = np.divide(df_test_rest_volt_diff,df_test_rest_time_dif)#电压对时间的微分
- df_test_rest_volt_diffdt = pd.DataFrame(df_test_rest_volt_diffdt_temp)
- df_test_rest_volt_diffdt = df_test_rest_volt_diffdt.append(df_test_rest_volt_diffdt.iloc[len(df_test_rest_volt_diffdt)-1])
- df_test_rest_volt_diffdt.columns = cellvolt_list
- if len(df_test_rest_volt_diffdt) > 25:
- for item in cellvolt_list:
- df_volt_diffdt_smooth = savgol_filter(df_test_rest_volt_diffdt[item],13,3)
- df_test_rest_volt_diffdt[item] = df_volt_diffdt_smooth
- df_test_rest_volt_diffdt['chrgr_rest'] = k
- df_test_rest_volt_diffdt['时间戳'] = list(df_rest_time)
- df_ini_volt['chrgr_rest'] = k
- df_ini_volt['时间戳'] = list(df_rest_time)
- k = k+1
- df_rest_volt_diffdt = df_rest_volt_diffdt.append(df_test_rest_volt_diffdt)#电压对时间的一次微分
- df_rest_volt_diffdt.reset_index()
- df_ini_volt_total = df_ini_volt_total.append(df_ini_volt)
- df_ini_volt_total.reset_index()
- #--------------------------------------------------------确认是否析锂----------------------------------------------------------------------------
- # df_lipltd_data = pd.DataFrame(columns=['sn','date','liplated'])
- m_num = 0
- df_fig_dvdtdata = pd.DataFrame()
- df_fig_voltdata = pd.DataFrame()
- for item in range(0,k):
- lipltd_confirm = []
- lipltd_amount = []
- df_check_liplated_temp = df_rest_volt_diffdt.loc[df_rest_volt_diffdt['chrgr_rest'] == item].reset_index(drop = True)
- df_check_volt_temp = df_ini_volt_total.loc[df_ini_volt_total['chrgr_rest'] == item].reset_index(drop = True)
- df_lipltd_volt_temp = df_check_liplated_temp[cellvolt_list]
- df_lipltd_volt_len = len(df_lipltd_volt_temp)
- df_data_temp_add = df_lipltd_volt_temp.iloc[df_lipltd_volt_len-3:df_lipltd_volt_len-1]#电压对时间的一次微分
- df_lipltd_volt_temp_add = df_lipltd_volt_temp.append(df_data_temp_add)
- # df_lipltd_volt_temp_dif = np.diff(df_lipltd_volt_temp_add,axis=0)#电压一次微分,计算dv/dt
- # df_lipltd_volt_temp_dif = pd.DataFrame(df_lipltd_volt_temp_dif)
- # df_lipltd_volt_temp_dif.columns = cellvolt_list
- df_lipltd_volt_temp_difdif = np.diff(df_lipltd_volt_temp_add,axis=0)#电压二次微分,判断升降
- df_lipltd_volt_temp_difdif = pd.DataFrame(df_lipltd_volt_temp_difdif)
- df_lipltd_volt_temp_difdif.columns = cellvolt_list
- df_lipltd_volt_temp_difdif_temp = df_lipltd_volt_temp_difdif
- df_lipltd_volt_temp_difdif_temp[df_lipltd_volt_temp_difdif_temp >= 0] = 1
- df_lipltd_volt_temp_difdif_temp[df_lipltd_volt_temp_difdif_temp < 0] = -1
- df_lipltd_volt_temp_difdifdif = np.diff(df_lipltd_volt_temp_difdif_temp,axis=0)#三次微分,利用-2,2判断波分和波谷
- df_lipltd_volt_difdifdif = pd.DataFrame(df_lipltd_volt_temp_difdifdif)
- df_lipltd_volt_difdifdif.columns = cellvolt_list
- df_lipltd_volt_difdifdif['chrgr_rest'] = k
- df_lipltd_volt_difdifdif['时间戳'] = list(df_check_liplated_temp['时间戳'])
- df_lipltd_volt_difdifdif = df_lipltd_volt_difdifdif.reset_index(drop = True)
- df_lipltd_data_temp = df_lipltd_volt_difdifdif.loc[df_lipltd_volt_difdifdif['时间戳'] < (df_check_liplated_temp['时间戳'][0] + datetime.timedelta(minutes=90))]
- for cell_name in cellvolt_list:#对每个电芯判断
- df_check_plated_data = df_lipltd_data_temp[cell_name]
- peak_pos = np.where(df_check_plated_data == -2)
- bot_pos = np.where(df_check_plated_data == 2)
- if len(bot_pos[0]) & len(peak_pos[0]):
- ini_dvdt = df_check_liplated_temp[cell_name][0]
- peak_dvdt = df_check_liplated_temp[cell_name][peak_pos[0][0] + 1]
- bot_dvdt = df_check_liplated_temp[cell_name][bot_pos[0][0] + 1]
- peak_hight = peak_dvdt - ini_dvdt
- peak_bot_hight = peak_dvdt - bot_dvdt
- liplted_amount_temp = (df_check_liplated_temp['时间戳'][bot_pos[0][0] + 1] - df_check_liplated_temp['时间戳'][0])/pd.Timedelta(1, 'min')
- if ((bot_pos[0][0] - peak_pos[0][0]) > 3) & (df_check_liplated_temp[cell_name][peak_pos[0][0] + 1] < 0) & (peak_bot_hight > 0.05*peak_hight) & (liplted_amount_temp > 15):
- lipltd_confirm.append(1)#1为析锂,0为非析锂
- lipltd_amount.append(liplted_amount_temp)
- else:
- lipltd_confirm.append(0)
- lipltd_amount.append(0)
- else:
- lipltd_confirm.append(0)
- lipltd_amount.append(0)
- if any(lipltd_confirm):
- temp = file.split('\\')
- sn_name = temp[11].split('.')[0]
- df_lipltd_confir_temp = pd.DataFrame({"sn":[sn_name], "time":[df_check_liplated_temp['时间戳'][0]], "liplated":[str(lipltd_confirm)], "liplated_amount":[str(lipltd_amount)]})
- df_lipltd_data = df_lipltd_data.append(df_lipltd_confir_temp)
- df_lipltd_data = df_lipltd_data.reset_index(drop = True)
- df_lipltd_data.sort_values(by = ['time'], axis = 0, ascending=True,inplace=True)#对故障信息按照时间进行排序
- df_fig_dvdtdata_temp = df_check_liplated_temp
- df_fig_dvdtdata_temp['chrgr_rest'] = m_num
- df_fig_dvdtdata = df_fig_dvdtdata.append(df_fig_dvdtdata_temp)#电压对时间微分数据
- df_fig_dvdtdata = df_fig_dvdtdata.reset_index(drop = True)
- df_fig_voltdata_temp = df_check_volt_temp
- df_fig_voltdata_temp['chrgr_rest'] = m_num
- df_fig_voltdata = df_fig_voltdata.append(df_fig_voltdata_temp)#原始电压数据
- df_fig_voltdata = df_fig_voltdata.reset_index(drop = True)
- m_num = m_num + 1
- df_lipltd_data.to_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂检测结果\MGMCLN750N215N155.csv',index=False,encoding='GB18030')
- df_fig_dvdtdata.to_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂检测结果\微分电压曲线.csv',index=False,encoding='GB18030')
- df_fig_voltdata.to_csv(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂检测结果\电压曲线.csv',index=False,encoding='GB18030')
-
- for i in range(0,m_num):
- fig = plt.figure(figsize=(20,10))
- df_fig_temp = df_fig_dvdtdata.loc[df_fig_dvdtdata['chrgr_rest'] == i]
- df_fig_temp = df_fig_temp.reset_index(drop=True)
- df_fig = df_fig_temp.loc[df_fig_temp['时间戳'] < (df_fig_temp['时间戳'][0] + datetime.timedelta(hours=1))]
- length = len(df_fig)
- df_hms_temp = pd.to_datetime(df_fig['时间戳'])#转换时间格式
- df_hms = df_hms_temp.dt.time#仅保留时分秒
- df_hms_fig = df_hms.apply(lambda x:x.strftime('%H:%M:%S'))
- for volt_num in cellvolt_name[0:10]:
- # plt.scatter([x for x in range(0, length)], df_fig[volt_num][0:length], label=volt_num)
- plt.plot(df_hms_fig, df_fig[volt_num],linewidth = 2, linestyle = '-', marker = 's',label=volt_num)
- mpl.rcParams['font.sans-serif']=['KaiTi']
- mpl.rcParams['axes.unicode_minus']=False #用来正常显示负号
- plt.legend()
- temp = file.split('\\')
- sn_name = temp[-1].split('.')[0]
- title = sn_name + '-' + df_fig['时间戳'][0].strftime('%y-%m-%d')#df_fig['device_id'][0] + '-' +
- plt.xlabel('时间', fontsize=16)
- plt.ylabel('电压的时间微分(mv/min)', fontsize=16)
- plt.xticks(range(1,len(df_hms_fig),5),rotation=45, fontsize=16)
- plt.yticks(fontsize=16)
- # plt.xlim((df_hms_temp[0]-datetime.timedelta(minutes=5)).dt.time,(df_hms_temp[0] + datetime.timedelta(hours=1.5)).dt.time)
- # plt.ylim(-2.5,0.5)
- plt.title(title, fontsize=20)
- # plt.show()
- plt.savefig(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂分析画图\析锂微分电压曲线\\'+title+'前.png', dpi=300)
- for i in range(0,m_num):
- fig = plt.figure(figsize=(20,10))
- df_fig_temp = df_fig_dvdtdata.loc[df_fig_dvdtdata['chrgr_rest'] == i]
- df_fig_temp = df_fig_temp.reset_index(drop=True)
- df_fig = df_fig_temp.loc[df_fig_temp['时间戳'] < (df_fig_temp['时间戳'][0] + datetime.timedelta(hours=1))]
- length = len(df_fig)
- df_hms_temp = pd.to_datetime(df_fig['时间戳'])#转换时间格式
- df_hms = df_hms_temp.dt.time#仅保留时分秒
- df_hms_fig = df_hms.apply(lambda x:x.strftime('%H:%M:%S'))
- for volt_num in cellvolt_name[10:21]:
- # plt.scatter([x for x in range(0, length)], df_fig[volt_num][0:length], label=volt_num)
- plt.plot(df_hms_fig, df_fig[volt_num],linewidth = 2, linestyle = '-', marker = 's',label=volt_num)
- mpl.rcParams['font.sans-serif']=['KaiTi']
- mpl.rcParams['axes.unicode_minus']=False #用来正常显示负号
- plt.legend()
- temp = file.split('\\')
- sn_name = temp[-1].split('.')[0]
- title = sn_name + '-' + df_fig['时间戳'][0].strftime('%y-%m-%d')#df_fig['device_id'][0] + '-' +
- plt.xlabel('时间', fontsize=16)
- plt.ylabel('电压的时间微分(mv/min)', fontsize=16)
- plt.xticks(range(1,len(df_hms_fig),5),rotation=45, fontsize=16)
- plt.yticks(fontsize=16)
- # plt.xlim((df_hms_temp[0]-datetime.timedelta(minutes=5)).dt.time,(df_hms_temp[0] + datetime.timedelta(hours=1.5)).dt.time)
- # plt.ylim(-2.5,0.5)
- plt.title(title, fontsize=20)
- # plt.show()
- plt.savefig(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂分析画图\析锂微分电压曲线\\'+title+'后.png', dpi=300)
- #-------------------------------------原始电压变化曲线-------------------------------------------------
- fig = plt.figure(figsize=(20,15))
- for i in range(0,m_num):#0,k
- # fig = plt.figure(figsize=(20,10))
- df_fig = df_fig_voltdata.loc[df_fig_voltdata['chrgr_rest'] == i]
- df_fig = df_fig.reset_index(drop=True)
- length = len(df_fig)
- temp = file.split('\\')
- sn_name = temp[-1].split('.')[0]
- title = sn_name + '-' + df_fig['时间戳'][0].strftime('%y-%m-%d')#df_fig['device_id'][0] + '-' +
- plt_data_len = len(df_fig)
- # for volt_num in cellvolt_name[5:6]:
- # plt.scatter([x for x in range(0, length)], df_fig[volt_num][0:length], label=volt_num)
- # plt.plot([x for x in range(0, plt_data_len)], df_fig[cellvolt_name[5]],linewidth = 2, linestyle = '-', marker = 's',label = title)
- plt.plot([x for x in range(0, plt_data_len)], df_fig[cellvolt_name[2]],linewidth = 2, linestyle = '-', marker = 's',label = title)
- # plt.plot(df_fig['时间戳'], df_fig[cellvolt_name[5]],linewidth = 2, linestyle = '-', marker = 's',label = title)#cellvolt_name[5]
- mpl.rcParams['font.sans-serif']=['KaiTi']
- mpl.rcParams['axes.unicode_minus']=False #用来正常显示负号
- plt.legend(fontsize=24)
- plt.xlabel('采样点', fontsize=24)
- plt.ylabel('电压(mV)', fontsize=24)
- plt.xticks(fontsize=20)
- plt.yticks(fontsize=20)
-
- # plt.xlim(df_fig['时间戳'][0]-datetime.timedelta(minutes=5),df_fig['时间戳'][0] + datetime.timedelta(hours=1.5))
- # plt.xlim(0, 30)
- # plt.ylim(4120, 4200)
- # plt.ylim(-2.5,0.5)
- plt.title('3#电芯不同时刻电压曲线', fontsize=30)
- plt.savefig(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\格林美-Catl7255\析锂分析画图\充电后静置电压曲线\\'+'3#电芯不同时刻电压曲线'+'.png', dpi=300)
- # # plt.show()
- # fig = plt.figure(figsize=(20,10))
- # for i in range(3,4):#0,k
- # # fig = plt.figure(figsize=(20,10))
- # df_fig = df_rest_volt_diffdt.loc[df_rest_volt_diffdt['chrgr_rest'] == i]
- # df_fig = df_fig.reset_index(drop=True)
- # length = len(df_fig)
- # temp = file.split('\\')
- # sn_name = temp[9].split('.')[0]
- # title = sn_name + '-' + df_fig['时间戳'][0].strftime('%y-%m-%d')#df_fig['device_id'][0] + '-' +
- # plt_data_len = len(df_fig)
- # # for volt_num in cellvolt_name[5:6]:
- # # plt.scatter([x for x in range(0, length)], df_fig[volt_num][0:length], label=volt_num)
- # # plt.plot([x for x in range(0, plt_data_len)], df_fig[cellvolt_name[5]],linewidth = 2, linestyle = '-', marker = 's',label = title)
- # # plt.plot([x for x in range(0, plt_data_len)], df_fig[cellvolt_name[2]],linewidth = 2, linestyle = '-', marker = 's',label = title)
- # plt.plot(df_fig['时间戳'], df_fig[cellvolt_name[5]],linewidth = 2, linestyle = '-', marker = 's',label = cellvolt_name[5])
- # mpl.rcParams['font.sans-serif']=['SimHei']
- # mpl.rcParams['axes.unicode_minus']=False #用来正常显示负号
- # plt.legend()
- # plt.xlabel('采样点', fontsize=14)
- # plt.ylabel('电压的时间微分(mv/min)', fontsize=14)
- # plt.xlim(df_fig['时间戳'][0]-datetime.timedelta(minutes=5),df_fig['时间戳'][0] + datetime.timedelta(hours=5))
- # # plt.xlim(0, 60)
- # # plt.ylim(-2.5,0.5)
- # plt.title('6#电芯不同时间电压微分曲线')
- # plt.savefig(r'D:\Work\Code_write\data_analyze_platform\USER\lzx\01算法开发\02析锂检测\01下载数据\MGMCLN750N215N049\\'+'6#电芯析锂'+'.png', dpi=300)
- # plt.show()
-
|