博主之前特意说过,excel就是csv的一种,那么在很多的商用数据中,不仅还用到csv还会用到excel,一旦数据量过大,综合处理就会成为一个问题,那么这就是python高超的地方了,今天博主用一段较长的代码来展示综合的操作
那么我们为了能够实现这段代码的学习,我们需要几个不同的文件。
下载地址
特意注明:博主所用的所有文件及代码都是引用《python数据分析基础》这本书的,其中的代码或经过博主改动,所有的文件都可以在这个网址里面下载到
我们打开这三个文件中任意一个会发现
开头的Number都是这几个数字,所以我们需要另外创建一个文件。使表格的开头是这几个数字,以便于后来的匹配。如图:
这是博主的匹配文件及输出文件。
我们不需要刻意去手动新建一个输出的csv文件,因为我们的python会帮我们创建
我们的目的是搜索出匹配开头那几个数字的所有数据,并找到其出处,成立出来
重点:我们需要进行搜索的三个文件一定要放在一个路径下,这个路径下不要带有其他的excel或者csv文件,后面大家就会知道为什么。
准备工作完成,代码
代码:
import csv
import glob
import os
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
items_find="E:\\桌面\\items_to_find.csv"
output_file="E:\\桌面\\output.csv"
items_to_find=[]
with open(items_find,"r",newline='') as item_number_csv_file:
filereader=csv.reader(item_number_csv_file)
for row in filereader:
items_to_find.append(row[0])
filewriter=csv.writer(open(output_file,"a",newline=""))#创建写入对象
file_count=0
line_count=0
count_for_item_number=0
for input_file in glob.glob(os.path.join("E:\\桌面\\file_archive",'*.*')):#第一个问题,路径需要用双斜杠来写
file_count+=1#文件读取没问题了
if input_file.split(".")[1]=="csv":
with open(input_file,"r",newline="") as fileread:
filereader=csv.reader(fileread)
header=next(filereader)
for row in filereader:
row_of_out=[]
for column in range(len(header)):
if column==3 :
cell_value=str(row[column]).strip("$").replace(",","").strip()
row_of_out.append(cell_value)
else:
cell_value=str(row[column]).strip()
row_of_out.append(cell_value)
row_of_out.append(os.path.basename(input_file))
if row[0] in items_to_find:#列表有问题。
filewriter.writerow(row_of_out)#肯定是写入进去的,而写入的唯一方法是这一条代码
print(row_of_out)
count_for_item_number+=1
line_count+=1
#csv文件的问题解决之后,看xlsx文件的问题
elif input_file.split(".")[1]=="xls" or input_file.split(".")[1]=="xlsx":
workbook=open_workbook(input_file)
for worksheet in workbook.sheets():
try:
header=worksheet.row_values(0)
except IndexError:
pass
for row in range(1,worksheet.nrows):
row_of_out=[]
for column in range(len(header)):
if worksheet.cell_type==3:
cell_value=xldate_as_tuple(worksheet.cell_value(row,column),workbook.datemode())
cell_value=str(date(*cell_value[0:3])).strip()
row_of_out.append(cell_value)
else:
cell_value=str(worksheet.cell_value(row,column)).strip()
row_of_out.append(cell_value)
row_of_out.append(os.path.basename(input_file))
row_of_out.append(worksheet.name)
if str(worksheet.cell_value(row,0)).split(".")[0].strip() in items_to_find:
filewriter.writerow(row_of_out)
count_for_item_number+=1
line_count+=1
- 头文件:处理多个多个文件自然而然要使用到glob,与os模块,所以开头引用。既然还要处理excel文件,那么我们又得注意引用datetime模块来格式时间,已经excel的读取模块xlrd
- 前面几行我们把需要匹配的数字都写入这个列表中,相信小伙伴们也能意识到,这个所谓的
完全是多余,哈哈没想到吧,其实我们只需要把所有需要匹配的数字填入一个列表中即可,这样做其实是为了以后处理特别大的csv或者excel时,我们这样会稍微方便一点。整个10到13行博主觉得完全是作者的恶趣味…。 - **filewriter=csv.writer(open(output_file,“a”,newline=""))**创建写入对象,这里小伙伴已经非常熟悉了。但是这个写法博主以前应该一直是使用以下写法写的。
其实两者是完全等价的,但是下面会对比较白的小伙伴比较友好,稍微熟悉的小伙伴就可以按博主上面的“新写法写”,简单,大气,上档次。 - 我们创建三个变量来计数。
- **for input_file in glob.glob(os.path.join(“E:\桌面\file_archive”,’.’))**这里我们使用for循环,glob以及os来读取这个路径下所有的文件,这个 前后的星号代表的是文件的名字和后缀,这样写代表所有文件,当然你可以后面的星号改为xlsx这样就只会读取所有的xlsx文件。
- 接下来我们来判断需要处理的是csv还是excel,我们只需要使用split函数将文件名以 . 隔开成为一个列表,利用他的后缀判断即可。
- if 后面的模块不需要讲解,相信小伙伴已经非常熟悉了,就是之前处理两种文件的不同写法。值得一提的是,这里我们用到了tyr expect语句,这个属于python中的异常处理,非常有用,大家可以去这里了解一下。
- 前面博主特意提醒不要将那个没用的items_to_find.csv与需要搜索的三个文件放在一个路径就是因为他也是一个csv文件,那么我们读取整个路径自然会读取到它,而它又只有几行没用的数字,那样我们的输出文件里面就会多出来几行完全没用的数据,虽然无伤大雅,但是对强迫症患者很不友好。