#7.生活小妙招-工业标准化数据简单处理(python数据处理)

#本次主要以动力电池测试的充放电数据为例,在未和python相遇的时候还手动进行数据处理,有时候项目进度紧急需要找好几个同事帮忙处理,效率缓慢,而且容易出现错误;使用python:pandas、matplotlib之后实现了数据处理的自动化,大大提升了效率与准确度:

数据链接(数据是测试版数据):
测试数据

1.实例1:电池模组循环寿命数据处理:
a.处理目标:
①.需要从原始数据里面筛选出如下表数据,放入表格里面(充放电末端的信息),对于表格内没有的最高最低电压及最高最低温度进行计算后插入表格:
在这里插入图片描述
b.原始数据格式:
①.文件夹(命名有规律,有利于数据处理,只拿一部分数据用于测试):
在这里插入图片描述
②.文件夹内部数据(excle数据):
在这里插入图片描述
③.数据格式(根据列标签对应的值和sheet的名字进行数据筛选):
在这里插入图片描述
c.数据处理:
①.数据读取:

#coding = gb2312
'''
#Exxx   Module循环测试数据整理
'''
import pandas as pd
import os
import numpy as np

#定义数据存储空间:
dfs = []   #存储读取到的数据(原始数据);
result_data = [] #存储数据处理后,得到得数据(结果数据);
dir = {}   #存储文件夹名字:因为os.listdir读取到的目录名字是没顺序的,所以分割后存入字典,可以有序的使用,形成新的路径;

#打开文件and读取数据,处理数据,保存数据:
class data_processing:
    #初始化函数,里面可以定义一些属性(就是常说得变量)
    def __init__(self):
        self.path = "D:\\python\\data_processing\\python\\E442循环寿命数据\\"
    #1.读取path目录下面的文件夹个数:
    def data_read(self):
        #目录名称存入字典,为了构造读取数据路径(如果存储文件夹规范一点,可以直接sort排序解决,但是这个路径不可以,因此采用字典):
        #不知道结果的,可以打印一下瞅一瞅;
        for i in range(len(os.listdir(self.path))):
            a,b = os.listdir(self.path)[i].split(".")
            dir[a] = b
        # print(frame['4'])
        # print(len(frame))
        #读取文件夹里面的数据
        for i in range(1,len(dir)+1,1):
            self.path1 = self.path+str(i)+"."+dir[str(i)]  #构造的路径
            # print(path1)
            for frame in os.listdir(self.path1):
                # 因为里面还有.xlsx结尾但是我们不需要的数据,所以加了个startswith限制一下;
                if frame.endswith(".xlsx") and frame.startswith("ExportData"): 
                    self.path2 = self.path1+'\\'+frame
                    print(self.path2)
                    #读取数据,并存入我们列表里面:
                    self.df = pd.read_excel(self.path2,sheet_name="TestData")
                    dfs.append(self.df)
                    print(self.df)
            print("第"+str(i)+"个文件夹读取成功")
        print("数据读取完成")
     
if __name__ == "__main__":
     #实例化我们的类:
     data = data_processing()
     #调用数据读取方法:
     data.data_read()

查看一下效果(数据很大读取较慢,我选取了其中两个数据):看到下面图片,读取数据成功,进行下一步,数据处理:
在这里插入图片描述
在这里插入图片描述
②.数据处理:就是使用各种方法实现我们的需求,代码我已经注释的很详细了,自己先看看,不懂的再沟通:

#coding = gb2312
'''
#Exxx   Module循环测试数据整理
'''
import pandas as pd
import os
import numpy as np

#定义数据存储空间:
dfs = []   #存储读取到的数据(原始数据);
result_data = [] #存储数据处理后,得到得数据(结果数据);
dir = {}   #存储文件夹名字:因为os.listdir读取到的目录名字是没顺序的,所以分割后存入字典,可以有序的使用,形成新的路径;

#打开文件and读取数据,处理数据,保存数据:
class data_processing:
    #初始化函数,里面可以定义一些属性(就是常说得变量)
    def __init__(self):
        self.path = "D:\\python\\data_processing\\python\\E442循环寿命数据\\"
    #1.读取path目录下面的文件夹个数:
    def data_read(self):
        #目录名称存入字典,为了构造读取数据路径(如果存储文件夹规范一点,可以直接sort排序解决,但是这个路径不可以,因此采用字典):
        #不知道结果的,可以打印一下瞅一瞅;
        for i in range(len(os.listdir(self.path))):
            a,b = os.listdir(self.path)[i].split(".")
            dir[a] = b
        # print(frame['4'])
        # print(len(frame))
        #读取文件夹里面的数据
        for i in range(1,len(dir)+1,1):
            self.path1 = self.path+str(i)+"."+dir[str(i)]  #构造的路径
            # print(path1)
            for frame in os.listdir(self.path1):
                # 因为里面还有.xlsx结尾但是我们不需要的数据,所以加了个startswith限制一下;
                if frame.endswith(".xlsx") and frame.startswith("ExportData"):
                    self.path2 = self.path1+'\\'+frame
                    print(self.path2)
                    #读取数据,并存入我们列表里面:
                    self.df = pd.read_excel(self.path2,sheet_name="TestData")
                    dfs.append(self.df)
                    print(self.df)
            print("第"+str(i)+"个文件夹读取成功")
        print("数据读取完成")

    #2.处理数据:
    def data_process(self):
        #计算处表格中最高最低电压及温度信息:
        for self.df in dfs:
            self.df.loc[:, "Tmax"] = self.df.loc[:, "Channel1_T01":"Channel1_T15"].max(axis=1)
            self.df.loc[:, "Tmin"] = self.df.loc[:, "Channel1_T01":"Channel1_T15"].min(axis=1)
            self.df.loc[:, "Vmax"] = self.df.loc[:, "Channel1_V01":"Channel1_V15"].max(axis=1)
            self.df.loc[:, "Vmin"] = self.df.loc[:, "Channel1_V01":"Channel1_V15"].min(axis=1)

            #将我们需要的信息过滤出来:按列名选取;
            self.df = self.df[["循环号", "工步名称", "功率(kW)", "工步充电容量(Ah)", "工步充电能量(kWh)", "工步放电容量(Ah)", "工步放电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]
            # df.set_index("循环号",inplace=True,drop=False) #inplace = True:不创建新的对象,直接对原始对象进行修改;inplace = False:对数据进行修改,创建并返回新的对象承载其修改结果
            
            #充电数据选取:
            #这里就是筛选出我们的数据,按照电压进行排序,因为充放电的电压末端都是数据里面的极大和极小,利用这个可以很方便的选取出数据;
            #这步骤往往是最难的,需要我们根据数据的特点进行数据选取;每个文件20圈,所以取前20行的数据;
            self.cc_data = self.df.sort_values(by=["Vmax"], ascending=False, axis=0)  # ascending=True升序,axis=0纵向排列;注意
            self.cc_data = self.cc_data.iloc[0:20, :]
            #根据循环号把数据顺序按升序排列:
            self.cc_data = self.cc_data.sort_values(by=["循环号"], ascending=True)
            self.cc_data = self.cc_data[["循环号", "工步名称", "工步充电容量(Ah)", "工步充电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]
            
            #放电数据选取:和充电思路一致:我们要去数据中验证我们的想法,不能自己想啥就是啥:
            self.dc_data = self.df.sort_values(by=["Vmin"], ascending=True, axis=0)
            self.dc_data = self.dc_data.iloc[0:20, :]
            self.dc_data = self.dc_data.sort_values(by=["循环号"], ascending=True)
            self.dc_data = self.dc_data[["循环号", "工步名称", "工步放电容量(Ah)", "工步放电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]
 
            #数据处理完毕后,我们对充放电数据进行合并:
            self.result = pd.merge(left=self.cc_data, right=self.dc_data, left_on="循环号", right_on="循环号")
            #数据加入新的列表:便于保存数据:
            result_data.append(self.result)
            print(self.result)
        print("数据处理完成")
        
if __name__ == "__main__":
     data = data_processing()
     data.data_read()
     data.data_process()      

查看一下效果,数据处理比数据读取还是要快的,读取到的数据已经基本很规整了,接下来就要储存数据了:
在这里插入图片描述
③.保存数据(完整代码):
保存数据有两种,一种是所有数据合并保存到一个sheet里面,一种是保存到多个sheet里面,看需求,我们这次采用的是第一种:

#coding = gb2312
'''
#Exxx   Module循环测试数据整理
'''
import pandas as pd
import os
import numpy as np
from pandas.core.frame import DataFrame
from openpyxl import load_workbook

#定义数据存储空间:
dfs = []   #存储读取到的数据(原始数据);
result_data = [] #存储数据处理后,得到得数据(结果数据);
dir = {}   #存储文件夹名字:因为os.listdir读取到的目录名字是没顺序的,所以分割后存入字典,可以有序的使用,形成新的路径;

#打开文件and读取数据,处理数据,保存数据:
class data_processing:
    #初始化函数,里面可以定义一些属性(就是常说得变量)
    def __init__(self):
        self.path = "D:\\python\\data_processing\\python\\E442循环寿命数据\\"
    #1.读取path目录下面的文件夹个数:
    def data_read(self):
        #目录名称存入字典,为了构造读取数据路径(如果存储文件夹规范一点,可以直接sort排序解决,但是这个路径不可以,因此采用字典):
        #不知道结果的,可以打印一下瞅一瞅;
        for i in range(len(os.listdir(self.path))):
            a,b = os.listdir(self.path)[i].split(".")
            dir[a] = b
        # print(frame['4'])
        # print(len(frame))
        #读取文件夹里面的数据
        for i in range(1,len(dir)+1,1):
            self.path1 = self.path+str(i)+"."+dir[str(i)]  #构造的路径
            # print(path1)
            for frame in os.listdir(self.path1):
                # 因为里面还有.xlsx结尾但是我们不需要的数据,所以加了个startswith限制一下;
                if frame.endswith(".xlsx") and frame.startswith("ExportData"):
                    self.path2 = self.path1+'\\'+frame
                    print(self.path2)
                    #读取数据,并存入我们列表里面:
                    self.df = pd.read_excel(self.path2,sheet_name="TestData")
                    dfs.append(self.df)
                    print(self.df)
            print("第"+str(i)+"个文件夹读取成功")
        print("数据读取完成")

    #2.处理数据:
    def data_process(self):
        #计算处表格中最高最低电压及温度信息:
        for self.df in dfs:
            self.df.loc[:, "Tmax"] = self.df.loc[:, "Channel1_T01":"Channel1_T15"].max(axis=1)
            self.df.loc[:, "Tmin"] = self.df.loc[:, "Channel1_T01":"Channel1_T15"].min(axis=1)
            self.df.loc[:, "Vmax"] = self.df.loc[:, "Channel1_V01":"Channel1_V15"].max(axis=1)
            self.df.loc[:, "Vmin"] = self.df.loc[:, "Channel1_V01":"Channel1_V15"].min(axis=1)

            #将我们需要的信息过滤出来:按列名选取;
            self.df = self.df[["循环号", "工步名称", "功率(kW)", "工步充电容量(Ah)", "工步充电能量(kWh)", "工步放电容量(Ah)", "工步放电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]
            # df.set_index("循环号",inplace=True,drop=False) #inplace = True:不创建新的对象,直接对原始对象进行修改;inplace = False:对数据进行修改,创建并返回新的对象承载其修改结果

            #充电数据选取:
            #这里就是筛选出我们的数据,按照电压进行排序,因为充放电的电压末端都是数据里面的极大和极小,利用这个可以很方便的选取出数据;
            #这步骤往往是最难的,需要我们根据数据的特点进行数据选取;每个文件20圈,所以取前20行的数据;
            self.cc_data = self.df.sort_values(by=["Vmax"], ascending=False, axis=0)  # ascending=True升序,axis=0纵向排列;注意
            self.cc_data = self.cc_data.iloc[0:20, :]
            #根据循环号把数据顺序按升序排列:
            self.cc_data = self.cc_data.sort_values(by=["循环号"], ascending=True)
            self.cc_data = self.cc_data[["循环号", "工步名称", "工步充电容量(Ah)", "工步充电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]

            #放电数据选取:和充电思路一致:我们要去数据中验证我们的想法,不能自己想啥就是啥:
            self.dc_data = self.df.sort_values(by=["Vmin"], ascending=True, axis=0)
            self.dc_data = self.dc_data.iloc[0:20, :]
            self.dc_data = self.dc_data.sort_values(by=["循环号"], ascending=True)
            self.dc_data = self.dc_data[["循环号", "工步名称", "工步放电容量(Ah)", "工步放电能量(kWh)", "Tmax", "Tmin", "Vmax", "Vmin"]]

            #数据处理完毕后,我们对充放电数据进行合并:
            self.result = pd.merge(left=self.cc_data, right=self.dc_data, left_on="循环号", right_on="循环号")
            #数据加入新的列表:便于保存数据:
            result_data.append(self.result)
        print(result_data[0],result_data[0].shape,type(result_data[0]))
        print("数据处理完成")

    # 3.保存数据;

    def data_save1(self):
        with pd.ExcelWriter("./ff.xlsx") as writer:
            # self.a = pd.concat([result_data[0],result_data[1]],ignore_index=True)
            self.a = pd.concat(result_data,ignore_index=True)
            self.a.loc[:,"循环号"] = self.a.index+1
            self.a.to_excel(writer, index=False)
        writer.save()
        print("存储完成")
        writer.close()

    # def data_save(self):
    #     self.c = 1
    #     with pd.ExcelWriter("./ff.xlsx") as writer:
    #         self.a = 1
    #         for self.df in self.result:
    #             self.name = str(self.a) + "圈"
    #             self.df.to_excel(writer, index=False, sheet_name=self.name)
    #             self.a = self.a + 1
    #             print("保存第", self.c, "圈")
    #             self.c = self.c + 1
    #
    #     writer.save()
    #     print("存储完成")
    #     writer.close()



if __name__ == "__main__":
     data = data_processing()
     data.data_read()
     data.data_process()
     data.data_save1()

查看保存的数据:
在这里插入图片描述
④.数据可视化(查看充放电容量随时间的变化):

from matplotlib import pyplot as plt
import matplotlib

#1.读取数据:
data = pd.read_excel("./ff.xlsx")

#汉字显示:
font = {"family":"MicroSoft YaHei","weight":"bold","size":8}
matplotlib.rc("font",**font)

#创建一个画布,画布上面有一行两列:
fig,(ax1,ax2) = plt.subplots(1,2)
#画布尺寸:
fig.set_size_inches(18,7)

#绘制充电曲线:##############################################图1
ax1.plot(range(1,len(data["工步充电容量(Ah)"])+1,1),data["工步充电容量(Ah)"],color="#F08080",label="充电容量")
#为图1设置标题,横坐标,纵坐标标题:
a = list(data["循环号"])[-1]
ax1.set_xticks(range(10,a+10,10))

xtick_lables = ["{}圈".format(i) for i in range(10,a+10,10)]
ax1.set_xticklabels(xtick_lables,rotation=45)

ax1.set_ylim([225,231])
ax1.set_yticks(range(225,231,1))

ax1.set_title("充电容量变化曲线")
ax1.set_xlabel("圈数")
ax1.set_ylabel("充电容量")
#添加图例:
ax1.legend(loc = "upper left")

#绘制网格:
ax1.grid(alpha=0.4)
##################################################################图2
#绘制放电曲线:
ax2.plot(range(1,len(data["工步放电容量(Ah)"])+1,1),data["工步放电容量(Ah)"],color="#F08080",label="放电容量")
#为图2设置标题,横坐标,纵坐标标题:
b = list(data["循环号"])[-1]
ax2.set_xticks(range(10,b+10,10))

xtick_lables = ["{}圈".format(i) for i in range(10,b+10,10)]
ax2.set_xticklabels(xtick_lables,rotation=45)

ax2.set_ylim([225,231])
ax2.set_yticks(range(225,231,1))

ax2.set_title("放电容量变化曲线")
ax2.set_xlabel("圈数")
ax2.set_ylabel("放电容量")
#添加图例:
ax2.legend(loc = "upper left")

#绘制网格:
ax2.grid(alpha=0.4)
#为整个图设置标题:
plt.suptitle("充放电容量随圈循环数变化曲线",fontsize=14,fontweight="bold")

# 1.保存图形:
plt.savefig("foo.png")
#2.保存为透明图像
plt.savefig("foo1.png", transparent=True)

plt.show()

在这里插入图片描述

2.实例2:电池系统循环寿命数据整理:
a.处理目标:
数据处理:需要将每一圈的充放电数据筛选出来, 并计算出每秒中充放电的容量 “累计AH”:数据包含:[“记录时间”, “Current”, “Tmax(℃)”, “Tmin(℃)”, “累计AH”, “温度”];使用公式计算出每个温度点充放电的总容量:数据包含:[“充电累计容量Tmax计算”, “充电累计容量Tmin计算”, “放电累计容量Tmax计算”,“放电累计容量Tmin计算”] 这样做的好处就是可以看出实际工作过程,每个温度点容量能量的消耗,对电池的实际使用有很大的指导意义:
在这里插入图片描述

b.原始数据格式:
①.文件夹格式:
在这里插入图片描述
②.文件夹内部数据:
在这里插入图片描述
③.文件内部数据格式:
在这里插入图片描述
c.数据处理:以下程序没有用类的方式进行书写,因为代码也不是很长;看到这觉得代码不够美观,可以使用函数或者类重新写一下,留作提升的部分吧;这个程序相对于第一个代码多了个分组聚合而已,不懂可以把函数复制到百度中,有很详细的讲解:

#coding = gb2312
import pandas as pd
import os
import numpy as np
'''
标准箱循环数据处理;
挑选出:记录时间,Current,Tmax(℃),Tmin(℃)
计算出每个温度下的充放电容量,然后根据Tmax(℃),Tmin(℃)分组,进行总容量的计算;

'''

#1.设置数据在底部窗口全部显示,便于观察:
pd.set_option("display.max_rows",500)
pd.set_option("display.max_columns",100)
pd.set_option("display.width",1000)

dfs = []
dfs1 = [] #存储最终数据

#2.打开文件:
for i in range(1,22,1):   #os.listdir()
    path = "D:\\python\data_processing\\python\\标准箱数据处理\\11.低温工况循环\\第"+str(i)+"圈\\"
    for frame in os.listdir(path):
        if frame.endswith(".xlsx"):
            df = pd.read_excel(path + frame, sheet_name="TestData")
            # print(path + frame)
            df = df[["记录时间", "电流(A)", "CAN_2\DBC\BMS_message_3_battery_high_temperature","CAN_2\DBC\BMS_message_3_battery_low_temperature"]]
            dfs.append(df)
    print("读取第",i,"圈")
print("读取完成")

#3.数据处理:
#a.更新数据的列名:
b = 1
for df in dfs:
    df.columns=["记录时间","Current","Tmax(℃)","Tmin(℃)"]

#b.添加"累计AH":
    for i in range(len(df["Current"])-1):
        df.loc[i, "累计AH"] = 1/ 3600 * df.loc[i, "Current"]

#c.根据Tmax(℃),Tmin(℃)分组,然后对"累计AH"求和:
    # 创建温度列:
    T = pd.DataFrame({"温度": range(-20, 56, 1)})
    #计算容量的总和:
    CC_Tmax = df.loc[df["累计AH"] >= 0].groupby("Tmax(℃)")["累计AH"].sum().to_frame().reset_index()
    CC_Tmin = df.loc[df["累计AH"] >= 0].groupby("Tmin(℃)")["累计AH"].sum().to_frame().reset_index()
    DC_Tmax = df.loc[df["累计AH"] < 0].groupby("Tmax(℃)")["累计AH"].sum().to_frame().reset_index()
    DC_Tmin = df.loc[df["累计AH"] < 0].groupby("Tmin(℃)")["累计AH"].sum().to_frame().reset_index()
    #对温度及容量总和合并,并与温度点对应:
    # print(CC_Tmax,CC_Tmin,DC_Tmax,DC_Tmin)
    t1 = pd.merge(T, CC_Tmax, left_on="温度", right_on="Tmax(℃)", how="left")
    t2 = pd.merge(t1, CC_Tmin, left_on="温度", right_on="Tmin(℃)", how="left")
    t3 = pd.merge(t2, DC_Tmax, left_on="温度", right_on="Tmax(℃)", how="left")
    t4 = pd.merge(t3, DC_Tmin, left_on="温度", right_on="Tmin(℃)", how="left")
    df = pd.concat([df, t4], axis=1)

    # df = df.drop("Tmax(℃)_x",axis=1, inplace=True)#不要这样写,报错了
    #删除不需要的列:
    df.drop(['Tmax(℃)_x','Tmin(℃)_x','Tmax(℃)_y','Tmin(℃)_y'], axis=1, inplace=True)
    #更新列名:
    df.columns = ["记录时间", "Current", "Tmax(℃)", "Tmin(℃)", "累计AH", "温度", "充电累计容量Tmax计算", "充电累计容量Tmin计算", "放电累计容量Tmax计算","放电累计容量Tmin计算"]
    # df.fillna(0, inplace=True) #以下两个命令都是把nan替换为0,看着美观一点,合理一点:
    df = df.replace(np.nan, 0)
#d.数据存储进列表:
    dfs1.append(df)
    print("处理第", b, "圈")
    b = b+1
print("处理完成")

# 3.保存数据;
c = 1
with pd.ExcelWriter("./xunhuan.xlsx") as writer:
    a = 1
    for df in dfs1:
        name = str(a) + "圈"
        df.to_excel(writer, index=False, sheet_name=name)
        a = a + 1
        print("保存第", c, "圈")
        c = c + 1

writer.save()
print("存储完成")
writer.close()

运行过程及结果:
读取:
在这里插入图片描述
处理:
在这里插入图片描述
保存:
在这里插入图片描述
结果展示:
在这里插入图片描述
在这里插入图片描述

以上就是两个实际的数据处理的实例,我们学习应该是学一个方法的,有些函数我们现在不会用没关系,因为编程需要接触的函数真的是多的记不住的,大部分函数我们需要了解他们的功能,等我们有问题的时候再去详细的了解一下是否可以解决;代码这个东西没有捷径,就是不断的使用,有想法的敲很多遍自然就会记得了;当然人的记忆也是有时限的,不要太相信自己的记忆,把学会的东西记录下来,作为自己的宝藏,后续用也会方便很多。

今天看到个动漫比较有意思记录一下,说的是一个修仙的故事,一群人来到一个远古大仙开辟的修炼场所,每个人都在吸收其中的灵气,但是有个天才少年也就是男主,资质简直了,灵气大部分被他给吸走了,于是其他人都要来灭杀他,他的同门为了救他基本牺牲殆尽,他修炼完成大杀四方,人们都说他被灵气摧毁了神智,但哪有人知道,他清醒的很,他只是在为同门报仇,故事到这里也就结束了;但是人们却又说了一句,他简直和800年前的逍遥子一模一样,一样失了神智,我们都明白了,从未有人在修炼之中失了神智,如果你失败了,你的模样还是你真实的模样吗?谁又会在乎真相呢。他们是天才,但有些事却也没得选;如果你还有的选,那你就是比大多数人幸福的。
持续更新,,,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值