目录
任务说明
在data的文件夹下又众多子文件夹,如图:
在利用机器学习的分类前需要对所有数据进行整合存在一个文件中,并且需要将距离分割出来作为特征之一,将波形和噪声分别作为labels(二分类问题);
软件设计
目标功能
- 功能一:读取文件数据
- 功能二:向excel写数据(并保证原数据不丢失)
- 功能三:遍历所有的文件夹
- 功能四:对文件名进行切割,提取出距离,根据文件名对数据添加标签;
import os
import xlrd
import xlwt
from os import listdir
from xlutils.copy import copy
from xlrd import open_workbook
from math import log
import re
# xpath是数据存放的路径
xpath="F:/RJ/dataProcess/data"
#这个是最后存数据用的文件
savefile = '4.xls'
#列出目录下所有文件
def list_all_files(rootdir):
_files = []
# subName = []
# listdir返回指定文件夹包含的文件或文件夹名称的列表
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
for i in range(0,len(list)):
# join函数作用是把目录和文件名合成一个路径,os.path中有split函数可以将路径和文件名称分隔开
path = os.path.join(rootdir, list[i])
# 注意append和extend的区别
# isdir判断是否为路径,isfile判断是否为文件
if os.path.isdir(path):
_files.extend(list_all_files(path))
if os.path.isfile(path):
_files.append(path)
return _files
#设置excel样式
def set_style(name,height,bold=False):
style = xlwt.XFStyle()
font = xlwt.Font()
font.name = name
font.bold = bold
font.color_index = 4
font.height = height
style.font = font
return style
# 使用xlwt进行写excel但是发现
#xlwt只能创建一个全新的文件重新写入内容保存,没有办法在保留原数据基础上增加数据
# 所以这里只用来写了一个特征行,即第一行
def write_excel():
f = xlwt.Workbook()
sheet1 = f.add_sheet('data', cell_overwrite_ok=True)
row0 = ["最大值(正峰)", "最小值(负峰)", "峰峰值", "均值(算术平均)", "方差", "峰度", "偏斜度", "时域能量", "频域能量", "均方根",\
"频段内能量(10-50)", "频段内能量(51-100)", "距离", "label"]
#写第一行
for i in range(0,len(row0)):
sheet1.write(0, i, row0[i], set_style('Times New Roman',220,True))
# for i in range(1, 5):
# for j in range(12):
# sheet1.write(i, j, 3)
f.save(savefile)
#为了弥补xlwt的缺陷重新引入一个函数库
#用xlutils修改文件
def add_excel(rowIndex, data, file):
rexcel = open_workbook(file)
# rowsNum = rexcel.sheets()[0].nclos
excel = copy(rexcel)
sheet = excel.get_sheet(0)
for i in range(len(data)):
sheet.write(rowIndex, i, data[i])
excel.save(file)
#获取下一级目录所有的名称和路径,和文件路径
# 用于方法一的设计,没有一次性遍历所有,这样在出现多级目录的情况下需要多次调用该函数
def getSubfolder(rootdir):
subName = []
subpath = []
subfile = []
FileList = listdir(rootdir)
m = len(FileList)
for i in range(m):
path = os.path.join(rootdir, FileList[i])
subName.append(FileList[i])
if os.path.isdir(path):
subpath.append(path)
if os.path.isfile(path):
subfile.append(path)
return subName, subpath, subfile
#读取excel中的数据
def read_excel(file):
outData = []#存储了所有合并单元格的数据,因为特征名字也合并了,所以也在这里
outClo1 = []#用于返回的数据
outCloLog = []#进过log处理后用于返回的数据
wb = xlrd.open_workbook(file)
sheet1 = wb.sheet_by_index(0)
#处理合并单元格的问题
merge = []
for (rlow, rhigh, clow, chogh) in sheet1.merged_cells:
merge.append((rlow, clow))
# !!!注意在这里做了一个排序,因为在输出的过程中发现是乱序的,为了保持和原有表格的一致性,将出现的序号排序再读取
merge = sorted(merge)
for index in merge:
outData.append(sheet1.cell_value(index[0], index[1]))
for data in outData:
if type(data).__name__ == 'float':#因为数据值为float型,所以根据类型将数据提取出来
#将第一列的数据单独提出来计算(从0开始)
#转换成了log函数处理
outClo1.append(data)
outCloLog.append(log(abs(data), 2))
# print(outClo1)
return outClo1
if __name__ == '__main__':
z = "噪声"
# 方法一:依次读取下一级文件夹的方式
# rowIndex = 0#用于记录所写过的行数
# subName, subpath, subfile = getSubfolder(xpath)#第一级目录读取,存放了下一级文件夹名称,路径,和子文件名称(这里subfile是空)
# write_excel()
# #处理每个子文件夹
# for j in range(len(subpath)):
# print(subpath[j])
# subName1, subpath1, subfile1 = getSubfolder(subpath[j])
# #处理子文件夹中的所有文件
# for i in range(len(subfile1)):
# print(subfile1[i])#这里添加一个打印文件名的原因是判断读取数据的顺序,对比最后的写入文件
# # 提取出来距离,这里用到的是正则表达式的知识
# distance = re.sub("\D", "", subfile1[i].split('\\')[-2])
# # 读取一个文件的数据,并将距离特征添加上
# colsData = read_excel(subfile1[i])
# if distance != '':#这里加一个判断的原因是环境噪声文件里面是''
# colsData.append(int(distance))#因为这里distance解析出来后是str
# # 判断是噪声文件还是波形文件,写入labels
# if z in subfile1[i].split('\\')[-1]:
# colsData.append(0)
# else:
# colsData.append(1)
# # 每读取一个子文件夹后添加一个行数,避免写的过程中出现重叠的情况
# add_excel(rowIndex+i+1, colsData, savefile)
# rowIndex = rowIndex + len(subfile1)
# 方法二:一次性遍历,依次处理子文件,而不是子文件夹
write_excel()
file = list_all_files(xpath)
for i in range(len(file)):
print(file[i])#与上同理,核对读写顺序
distance = re.sub("\D", "", file[i].split('\\')[-2])
colsData = read_excel(file[i])
if distance != '': # 这里加一个判断的原因是环境噪声文件里面是''
colsData.append(int(distance)) # 因为这里distance解析出来后是str
if z in file[i].split('\\')[-1]:
colsData.append(0)
else:
colsData.append(1)
# 这里是一次性读写文件,所以直接用i记录即可,+1是因为第一行用来放名称了
add_excel(i + 1, colsData, savefile)
效果
完成了对于数据的转移;
参考文献
python中os.path()模块:Python os.path 模块 | 菜鸟教程
Python遍历文件夹下的所有文件:python 遍历目录(包括子目录)下所有文件_一些和风旭日的日子的博客-CSDN博客
追加excel数据:Python读写/追加excel文件Demo_孔天逸的博客-CSDN博客
python中正则表达式的使用:Python 正则表达式 | 菜鸟教程