你是否因为科研太勤奋导致数据太多而感到焦虑,你是否因为机械处理重复数据而感到枯燥,你是否因为虽有数据而画不出简明易懂的图而感到烦恼?
好消息!好消息!科研神器Python之数据处理-简要介绍开讲啦。Python作为一种结合了解释性、编译性、互动性和面向对象特征的高级语言,由于其语言的简洁性、易读性以及可扩展性使得非计算机专业的人员能够很好地掌握并使用其来开发自己的实用小程序。在这过程中,开发者不用关心底层的实现,通过简单地调用“编程大佬”们封装好的类库以及接口便可以实现想要的各种功能。因此Python很适合材料、化学等领域的科研人员学习来简化科研中遇到的大量数据处理等任务。
结合自身在BMG课题组科研过程中遇到的大量需要机械式处理的重复数据以及学习Python的历程,在这篇科普文中,我给大家介绍一下我在用Python在处理这类数据时的常用套路。
1. Python语言基础入门
工欲善其事,必先利其器,在使用Python之前,你得了解Python中常用的数据类型,如字符串,数字,列表,元组,字典等。不同函数的输入的数据类型往往不同,需要数据类型的转换与函数对应一致。注意此外,还得掌握循环语句以及判断语句的用法,语句的原理和高中学习的流程图类似。在此基础上,最好掌握简单自定义函数的编写以及面向对象编程中类的概念,这对以后我们使用开源类库很有帮助。学完这些简单的基础知识以后,我们就可以编写自己的处理数据小程序啦!
2. 选择合适的数据容器
在处理数量庞大的数据之前,我们得先寻找到合适的数据容器来暂时地将我们所获得的科研数据装载到Python程序中,这样我们才能够对在计算机内存中对这些数据进行加减乘除,平滑,积分,微分等运算。常见的数据容器有列表,numpy矩阵以及在numpy基础上开发而来的pandas带行列标签的一维多维数据容器。其中列表是Python的基础数据容器,而numpy和pandas是第三方类库,需要另外安装后使用。这两种第三方类库都有现成的接口用来打开和装载常见的文件格式,例如.txt,.csv,.xlsx等。除此之外,对于一些特殊的文件格式,例如,布鲁克红外获得的OPUS文件,可以简单地调用第三方包brukeropusreader来加载单谱文件并返回波数与吸收值对应的两列数据。举个栗子,以Instron拉伸机产生的数据为例。通常Instron的原始数据为.csv文件,并且每次测样都会以单独的.csv文件储存,这样当我们进行50组样品测试时,最后软件便会保存50个.csv文件。这样想要处理这些数据就会非常繁琐,得需要重复50次打开文件复制数据操作才能将50组数据汇总画出我们需要的力学曲线来。而利用Pandas库的.read_csv方法,我们便可以轻松地将数据隐式地“打开”,并且可以通过Pandas库提供的行列索引提取我们想要的行列数据并将其添加到同一个数据容器(如列表)中。在此基础上,写一个循环结构,便可以实现程序顺序打开50个.csv文件并将每个文件中想要的行列数据提取汇总到同一个数据容器,最后通过一个写入操作,将汇总数据写入到单个文件中去。
3. 学会站在巨人的肩膀上—第三方库
Python作为一种高级的语言,其拥有完善的社区,以及强大的第三方库。在这些有些的库中,各种功能的代码被高度抽象,我们无需花费时间为了实现某个功能而设计算法,可以更多地关注到问题的本身。很多情况下,我们仅需要数行代码,便可以实现很复杂的功能。以信号平滑处理中的Savizkg-Golag滤波为例,通过调用第三方科学计算库Scipy中的.signal.savgol_filter方法,便可以通过一行代码实现光谱信号的平滑处理。在科学绘图中,我们可以通过调用Matplotlib库利用简单的几行代码便实现数百种风格样式的可视化图来。在Python中,站在巨人的肩膀上,你可以看的更远。
4. 一个实用的Instron拉伸机数据处理小程序
简单说了这么多,下面看看一个完整的数据处理小程序吧~(对上述50组样品数据利用以下程序进行处理,整个数据处理时间可缩减到一分钟内)
#-*- encoding: utf-8 -*-# Author by Chao Ye# Instron数据处理程序# Version 3.0#导入需要的第三方库import xlwt #用于读写excel文件库import numpy as np #常用数据容器import easygui as g #简单的GUI操作库import os #获取系统信息import matplotlib.pyplot as plt #科学绘图库import pandas as pd #带行列标签的数据容器#选择原始数据目录title = g.msgbox(msg="本程序由Chao Ye赞助",title="Instron 数据处理程序",ok_button="开始并选择原始数据目录")tt = '请选择原始数据所在的目录'default = 'C:/Users'path = g.diropenbox(msg="请选择",title=tt, default=default)path=str(path).replace("\\","/")#将输入的默认路径改为python能够识别的路径path=path+"/"print("你选择的路径为:"+path)#获取原始文件数量并将第一个文件装载到pandas容器中进行数据定位txtfiles= os.listdir(path)data = pd.read_csv(path+txtfiles[0],header=None,\ encoding='gbk',delimiter=',',error_bad_lines=False,\ skip_blank_lines=False,names=["1", "2", "3", "4", "5","6","7"])#print(data["1"])#print(data["1"].loc["0"])for i in range(0,200): if data.iloc[i,0]=="时间": t = ifor ii in range(0,7): string=data.iloc[t,ii] if string[2:4]=="应变": a=ii breakfor ii in range(0, 7): string = data.iloc[t, ii] if string[2:4]=="应力": b=ii breaks=t+1if data.iloc[s, a]=="(%)": q=1else: q=0t=t+2#询问用户是否需要校准样品截面积,选择是的话将会自动重算应力c = g.ccbox(msg='是否需要校准截面?', title='附加功能', choices=('是', '否'), image=None)if c: area_str = g.enterbox(msg="输入样品真实面积用英文','隔开", title="样品真实面积") area_origin = eval(g.enterbox(msg="输入样品测试时输入面积", title="样品测试面积")) area_list = area_str.split(",") print("原始面积:", area_origin) print("你输入的面积分别为:", area_list)else: #area_path = "nan" print("数据处理中")print("测样数为:",len(txtfiles))datas_total = []#批量打开数据并绘图plt.style.use(["science",'no-latex'])#用science文献绘图风格fig,ax = plt.subplots()for x in range(len(txtfiles)): list3 = [] data = np.loadtxt(path+txtfiles[x],dtype=str,delimiter=",",skiprows=t) data1 = data[:,a] #读取应变列 data2 = data[:,b] #读取应力列 list1=data1.tolist() #将numpy数据转化为列表 list2=data2.tolist() #将numpy数据转化为列表 list1= [eval(eval(x)) for x in list1] list2= [eval(eval(x)) for x in list2] if c: for ii in list2: ii=ii*area_origin/eval(area_list[i]) list3.append(ii) else: list3=list2 x=np.array(list1) y = np.array(list3) ax.plot(x, y) datas_total.append(list1) #将数据装入大的列表中 datas_total.append(list3)#ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))ax.set_xlim(left=0)ax.set_ylim(bottom=0)if q==1: ax.set_xlabel('Strain (%)')elif q==0: ax.set_xlabel('Strain')ax.set_ylabel('Stress (MPa)')ax.set_title('')#ax.legend()plt.show()#ax.autoscale(tight=True)fig.savefig(path+'fig1.pdf')fig.savefig(path+'fig1.svg', bbox_inches = 'tight',dpi=300)print("数据处理完毕,等待保存")#保存汇总数据f = xlwt.Workbook() # 创建工作bosheet1 = f.add_sheet(u'sheet1',cell_overwrite_ok=True) #创建工作簿for y in range(len(datas_total)): j = 0 ii = datas_total[y] # for datas in datas_total: for iii in ii: sheet1.write(j,y,iii) #循环写入 竖着写 j=j+1f.save(path+"数据汇总.xls") # 保存xls文件g.msgbox(msg="数据处理完毕,已保存至原始数据目录,点击退出",title="Supported by ChaoYe",ok_button="结束!")
大家对小程序有什么建议,欢迎留言哦! 编辑:王洋 ,崔静,杨硕