批量从含有多列数据的txt文件中提取某个数据,并存入csv文件
- 任务需求与解读
- 代码实现
- 导入相关库
- 提取txt文件的三列数据存为列表
- 按条件提取某个数据存入字典
- 将字典写入csv文件
任务需求与解读
昨天收到一个需求,希望能将电化学工作站的数据文件(.bin后缀)转为txt文件,并从txt文件中提取某个电位对应的电流,然后再找这个电流的一半所对应的电位,将以上这些数据提取出来,存入csv文件中。任务图示见下,
这个任务实际主要分两步:
- 第一,将bin文件转为txt文件;
- 第二,读入txt文件,提取数据,存入csv文件。
由于不清楚电化学工作站是以什么样的编码方式将数据存入二进制bin文件,使用python很难解码,尝试了多种模块也没有成功 。因此对于第一步,只能选择手动通过电化学工作站专有的软件,将bin文件转为txt文件。最后任务只需要实现从txt文件中提取数据,并存入csv文件。
代码实现
实现从txt文件中提取某个电位对应的电流,然后再找这个电流的一半所对应的电位,将以上这些数据提取出来,存入csv文件中。
【代码思路设计】
- 读入txt文件,定位到数据部分;
- 将数据提取存储到列表中;
- 根据条件定位到列表元素,提取所需数值,存入列表;
- 使用for循环遍历每一份txt文件,实现步骤1-3,最后将所有提取的数据写入csv文件;
导入相关库
import os
import csv
import copy
import datetime
import numpy as np
提取txt文件的三列数据存为列表
该函数用于实现提取txt文件的三列数据,存储在列表中
file_path:txt文件路径
【实现步骤】
- 首先按行读入txt文件,去掉每行的前后空格,存成新列表;
- 定位到txt文件内数据的前一行,即’Segment 1:'处;
- 将每行数据根据逗号’,'分离,分别存入三个空列表; 即可得到分别存储了txt文件三列数据的三个列表。
def get_alldata(file_path):
'''
该函数用于实现提取txt文件的三列数据,存储在列表中
file_path:txt文件路径
实现步骤:
首先按行读入txt文件,去掉每行的前后空格,存成新列表;
定位到txt文件内数据的前一行,即'Segment 1:'处;
将每行数据根据逗号','分离,分别存入三个空列表;
即可得到分别存储了txt文件三列数据的三个列表。
'''
data_L=[]
with open(file_path,'r') as f:#打开txt文件
lines=f.readlines()#按行读取文件,并按行存储为列表
new_lines=[]#建立新列表,存储去掉前后空格后的元素
for line in lines:#遍历存储了文件信息的列表
line = line.strip()#去掉每个元素中的前后空格
new_lines.append(line)#存储去掉前后空格后的元素
start_site=new_lines.index('Segment 1:')#定位到数据前的位置
for i in range(start_site+1,len(new_lines),1):
xyz=new_lines[i].split(',')#对列表元素根据逗号','分离为新列表
xyz_cp=copy.deepcopy(xyz)#对列表进行深复制
data_L.append(np.array(xyz_cp).astype('float64'))#将数据存入列表
potential_L=[i[0] for i in data_L]#txt第一列数据
diskcurrent_L=[i[1] for i in data_L]#txt第二列数据
ringcurrent_L=[i[2] for i in data_L]#txt第三列数据
return potential_L,diskcurrent_L,ringcurrent_L
【输出示例】
file_path=r'D:\desks\test.txt'
potential_L,diskcurrent_L,ringcurrent_L=get_alldata(file_path)
print(potential_L[0],diskcurrent_L[0],ringcurrent_L[0])
0.2 3.772e-05 2.617e-06
按条件提取某个数据存入字典
【两个条件】
第一,已知第一列数据想要的数值,提取相同行数对应的第二、第三列数据;
第二,已知第二列数据想要数值的一半,找到第二列相近数值,提取相同行数对应的第一、第三列数据;
对于第一个条件,可以使用列表索引实现定位;对于第二个条件,使用已知数值与第二列所有数据作差,找出差值绝对值最小的,就是所需要找的第二列数值,然后使用列表索引实现其他两列数据的定位。
【代码实现】
该函数用于实现提取指定电压下的电流,并寻找半电流下的电位。
txt_folderdir:txt文件夹所在路劲
txt_foldername:txt文件夹名
【实现步骤】
- 首先定义好存储了txt文件夹的路径,将路径下的txt文件名存为列表,方便后面进行一份份遍历txt文件;
- 遍历txt文件,获取txt文件中的三列数据; 根据规定的电位,找出对应的盘电流、环电流,存入字典,存储格式是{txt文件名:数据};
- 接着计算盘电流的一半,使用该数值逐一与盘电流中的所有数值做差,找出差值的绝对值最小所对应的盘电流,这个盘电流就是我们需要找的一半;
- 根据找到的盘电流所在位置,找到对应的电压与环电流,分别存入字典;
- 以上便完成了数据的提取
。
def get_specifieddata(txt_folderdir,txt_foldername,potential):
'''
该函数用于实现提取指定电压下的电流,并寻找半电流下的电位
txt_folderdir:txt文件夹所在路劲
txt_foldername:txt文件夹名
实现步骤:
首先定义好存储了txt文件夹的路径,将路径下的txt文件名存为列表,方便后面进行一份份遍历txt文件;
遍历txt文件,获取txt文件中的三列数据;
根据规定的电位,找出对应的盘电流、环电流,存入字典,存储格式是{txt文件名:数据};
接着计算盘电流的一半,使用该数值逐一与盘电流中的所有数值做差,找出差值的绝对值最小所对应的盘电流,这个盘电流就是我们需要找的一半;
根据找到的盘电流所在位置,找到对应的电压与环电流,分别存入字典;
以上便完成了数据的提取。
'''
txt_folderpath=os.path.join(txt_folderdir,txt_foldername)#txt文件所在路径
txt_files=os.listdir(txt_folderpath)#遍历txt文件夹中的所有文件,将文件名存储在列表中
#建立字典存储数据,存储方式均为{文件:数据}
potential_dict={}#存储{文件:电位}
half_potential_dict={}#存储{文件:半电位}
diskcurrent_dict={}#存储{文件:电位对应的盘电流}
half_diskcurrent_dict={}#存储{文件:半电位对应的盘电流}
ringcurrent_dict={}#存储{文件:电位对应的环电流}
half_ringcurrent_dict={}#存储{文件:半电位对应的盘电流}
for file in txt_files:
file_path = os.path.join(txt_folderpath,file)#txt文件所在路径
potential_L,diskcurrent_L,ringcurrent_L=get_alldata(file_path=file_path)#txt文件中的三列数据
#首先提取某电位对应的电流
potential_index=potential_L.index(potential)#定位到电压为-0.5的位置
diskcurrent=diskcurrent_L[potential_index]
ringcurrent=ringcurrent_L[potential_index]
#print(diskcurrent,ringcurrent)
potential_dict[file[:-4]]=potential
diskcurrent_dict[file[:-4]]=diskcurrent
ringcurrent_dict[file[:-4]]=ringcurrent
#print(potential_dict,diskcurrent_dict,ringcurrent_dict)
#下面提取半电流对应位置
half_current_theory=diskcurrent/2
diff_L=[]
for current in diskcurrent_L:
diff=abs(half_current_theory-current)#计算差值的绝对值
diff_cp=copy.deepcopy(diff)
diff_L.append(diff_cp)
half_current_index=diff_L.index(min(diff_L))#定位到绝对值最小的位置
half_current_calc=diskcurrent_L[half_current_index]#找到对应电流
#print(file,half_current_index,half_current_calc)
#根据找到的位置,分别找出对应的电位与环电流
half_potential_dict[file[:-4]]=potential_L[half_current_index]
half_diskcurrent_dict[file[:-4]]=diskcurrent_L[half_current_index]
half_ringcurrent_dict[file[:-4]]=ringcurrent_L[half_current_index]
#print(half_potential_dict,half_diskcurrent_dict,half_ringcurrent_dict)
return potential_dict,half_potential_dict,diskcurrent_dict,half_diskcurrent_dict,ringcurrent_dict,half_ringcurrent_dict
将字典写入csv文件
将上面提取的数据存入csv文件
def write_data_tocsv(txt_folderdir,txt_foldername,potential):
'''
该函数实现将提取的数据存入csv文件
'''
save_csvdir=os.path.join(txt_folderdir,txt_foldername+'_data_to_csv')
if not os.path.exists(save_csvdir):
os.makedirs(save_csvdir)
potential_dict,half_potential_dict,diskcurrent_dict,half_diskcurrent_dict,ringcurrent_dict,half_ringcurrent_dict=get_specifieddata(txt_folderdir,txt_foldername,potential)
#将前面存储了文件名及相应数据的字典按列存储在csv文件中
mkfile_time = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S')#这里是运行时对应的日期
rows = zip(potential_dict.keys(),potential_dict.values(),diskcurrent_dict.values(),ringcurrent_dict.values(),half_potential_dict.values(),half_diskcurrent_dict.values(),half_ringcurrent_dict.values())
with open(os.path.join(save_csvdir,'data_to_csv_'+mkfile_time+'.csv'), "w", newline='') as f:
writer = csv.writer(f)
# 标题行写入
header = ['txt文件名','电压', '盘电流','环电流','半盘电流对应的电压','半盘电流','半盘电流对应的环电流']
# 数据写入
csvrow1 = []
csvrow2 = []
csvrow3 = []
csvrow4 = []
csvrow5 = []
csvrow6 = []
csvrow7 = []
csvrow1.extend('txt文件名')
csvrow2.extend('电压')
csvrow3.extend('盘电流')
csvrow4.extend('环电流')
csvrow5.extend('半盘电流对应的电压')
csvrow6.extend('半盘电流')
csvrow7.extend('半盘电流对应的环电流')
writer.writerow(header)
writer.writerows(rows)
【代码运行】
txt_folderdir=r'D:\desk\bin'
txt_foldername='txt_file'
potential=-0.5
write_data_tocsv(txt_folderdir,txt_foldername,potential)
【csv文件输出】