背景

python处理数据最重要的就是诸如numpy、pandas这种工具了

接到媳妇儿的一个需求,要我帮她将多个文件夹的txt文件按照文件夹写入到按照文件夹命名的Excel中。本打算用java来实现,搞了一个小时决定放弃,哈哈哈。java还是适合写点crud和web项目。

于是,我又捡起来荒废已久的python。这种数据处理类,我还是喜欢即写即得的jupyter notebook。

第一步:遍历文件夹取得所有txt文件并修正:

概述

  • os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。这个列表以字母顺序。 它不包括 ‘.’ 和’…’
    即使它在文件夹中。
  • 只支持在 Unix, Windows 下使用。

语法

  • listdir()方法语法格式如下:
os.listdir(path)

参数

  • path – 需要列出的目录路径;

返回值

  • 返回指定路径下的文件和文件夹列表;

例子:获取文件夹中所有txt文件,并改写其中部分内容

文件样例:

name is not you!
xxx      xxx1        xxx2     
0.8361      1           1           
1.6722      3           2           
2.5083      1           3

我需要将第一行删除,并且用第二行作为列索引,写入excel中,那么先修正一下txt文件。

#获取文件路径下的所有文件
files =os.listdir("/Users/naosangcuo/Documents/TXT/")
for file in files:
    print(file)
    #排除以.开始的文件
    if not file.startswith('.'):
        #获取下一层的所有文件
        txtNames =os.listdir("/Users/naosangcuo/Documents/TXT/"+file)
        for txtName in txtNames:
            #获取这层文件夹里面以.txt结尾的文件
            if txtName.endswith(".txt"):
                print(txtName)
                txt ="/Users/naosangcuo/Documents/TXT/"+file+'/'+txtName
                print(txt)
                #删除掉第一行
                files = open(txt,'r+')
                Lines  = files.readlines()
                #将第一行置为空
                Lines[0]= ''
                files.close()
                files = open(txt,'w+')
                Lines = files.writelines(Lines)
                files.close()
                print(txtName)

第二步:将多个txt文件按照文件夹写入不同的excel中

这里我使用pandas中read_table函数来实现txt的读写:read_table会将txt按照某种方式进行读取为DataFrame这种数据结构,并且一只使用第一行作为索引,或者自己指定索引。转为DataFrame了,就可以使用pandas来进行很多改造了。然后使用to_excel函数来完成写入到excel的工作。

read_table参数如下:

pandas.read_table(filepath_or_buffer,sep='\t',delimiter=None,
                  header='infer',names=None,index_col=None,usecols=None,squeeze=False,
                  prefix=None,mangle_dupe_cols=True,dtype=None,engine=None,converters=None,
                  true_values=None,false_values=None,skipinitialspace=False,skiprows=None,
                  nrows=None,na_values=None,keep_default_na=True,na_filter=True,verbose=False,
                  skip_blank_lines=True,parse_dates=False,infer_datetime_format=False,
                  keep_date_col=False,date_parser=None,dayfirst=False,iterator=False,
                  chunksize=None,compression='infer',thousands=None,decimal=b'.',lineterminator=None,
                  quotechar='"',quoting=0,escapechar=None,comment=None,encoding=None,dialect=None,
                  tupleize_cols=None,error_bad_lines=True,warn_bad_lines=True,skipfooter=0,
                  doublequote=True,delim_whitespace=False,low_memory=True,memory_map=False,
                  float_precision=None)
ilepath_or_buffer   第一个参数,把文件地址传入即可;
engine='python'      默认是c引擎解析,如果使用python引擎,可以解析更丰富的内容;
header='infer'       默认会自动推断数据文件头,如果设置为None则无文件头,为1则第一行是文件头;
sep='\t'             默认是由tab分割的数据,如果是其他可以另改,比如','
当然还有很多参数可以使用,请按需使用,不会的看看文档http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_table.html

样例

#考虑读取一列内容
import pandas as pd
test1 = pd.read_table(skipinitialspace=True,index_col=False) # 这个是带有标题的文件,以第一行为标题
test1.drop(columns='Unnamed: 3',inplace=True) #清除多余的一列

dataframe 写入excel

由于前面已经转成dataframe了现在我们只需要写入到excel中就好了:

由于我们又多个txt所以,多个dataframe需要写入同一个excel中,每次使用df.to_excel(文件名)的形式去写,系统都会重新创建一个新的文件。也就意味着前面的文件会被覆盖掉,你得到的只能是最后一个df写入的结果文件:我们通过创建一个ExcelWriter对象,可以解决上面的问题

writer = pd.ExcelWriter(os.path.join(os.getcwd(), '自定义.xlsx'))
df1.to_excel(writer, sheet_name='自定义sheet_name')#startcol=**, startrow=**)
df2.to_excel(writer, sheet_name='自定义sheet_name')#startcol=**, startrow=**)
df3.to_excel(writer, sheet_name='自定义sheet_name')#startcol=**, startrow=**)
...
 
writer.save()# 写入硬盘
# 不传sheet_name参数时,默认多个dataframe会写入同一个xlsx文件的同一个sheet里
# 传sheet_name参数时,多个dataframe会写入同一个xlsx文件的不同sheet里

# startrow, startcol 不传时默认dataframe在excel里在sheet1里其实行列都是一,
# 需注意,python和excel的索引起始数字不同,如果startrow=2, startcol=4,不是从第二行第四列开始写,而是从第三行第五列开始写

好了最后看下我整体的实现:

import time
import math
import os
import sys
import os, os.path,shutil
import pandas as pd
#批处理
files =os.listdir("/txt/")
i=1
col=0
row=2
data=[]
#因为我这里还需要用txt的名字作为标题,所以另外起一个字典来做这个事情
dictName={}
writer =pd.ExcelWriter('/txt/4.xlsx')#若没有这个文件会自己创建
for file in files:
    if file.endswith(".txt"):
        txtName ="/txt/"+file
        print(txtName)
        dictName.update({i:file.split('.')[0]})
        i=i+1
        dictName.update({i:" "})
        i=i+1
        data.append(pd.read_table(txtName,skipinitialspace=True,index_col=False)) # 这个是带有标题的文件
df = pd.DataFrame([dictName])
df.to_excel(writer, startcol=0,index=None)
for item in data:
    item.drop(columns='Unnamed: 3',inplace=True) #清除多余的一行
    item.to_excel(writer, startcol=col,startrow=row,index=None)#index=none表示不写入行标
    col=col+3 每个写入又间隔
writer.save()

然后又需要将某行到某行到均值写到另外一个sheet里面

import time
import math
import os
import sys
import os, os.path,shutil
import pandas as pd
import openpyxl
import xlwings as xw
files =os.listdir("path")
for file in files:
    print(file)
    if file.endswith(".xlsx"):
        tabledata = pd.read_excel("path"+file, header=0)
        data1=tabledata[0:1]
        #取某行到某行到数据
        data2=tabledata[358:368]
        #求列均值并列转行,我这里直接利用dic进行列转行,又更好到形式单并不是适用于我
        dict2=data2.mean(0).to_dict()
        df2 = pd.DataFrame([dict2])
        writer =pd.ExcelWriter("path"+file)
        tabledata.to_excel(writer,sheet_name="data",startrow=0,index=None)
        data1.to_excel(writer,sheet_name="mean",startrow=0,index=False,header=False,index_label=None)
        data2.to_excel(writer,sheet_name="mean",startrow=1,index=False,header=False,index_label=None)
        df2.to_excel(writer,sheet_name="mean",startcol=0,startrow=11,index=False,header=False,index_label=None)
        writer.save()

 


参考文献:https://zhuanlan.zhihu.com/p/85918022