Python 与 Excel 表格综合实例:处理校运会报名 Excel 表格,多表整合、数据汇总及统计实例
前言:
上一篇博客,介绍了一个简单的实例:给已有Excel表格添加序号、增加新列,主要是介绍 xlrd 与 xlwt 两个模块是如何在一起工作的。
这一篇我们来介绍另外一个实例,相对来说会复杂与贴近日常工作一点。
需求:
假设:需完成一份报名工作,将已做好报名表下发到各个报名单位。他们按格式填好报名表、上交,最后由你负责信息汇总和统计。
这样一份任务其实比较简单、常见,但当报名单位众多,如有几千份报名表需要统计时,个人操作起来还是很费时费力的,也可能会出现信息统计错误的情况。
模拟的具体案例:完成校运会报名表汇总、统计工作。
假设每个班级按校运会报名表填写了该班级的学生报名信息,需要你汇总、统计成一张Excel表格。
Excel表格 汇总信息 sheet 里包含所有学生的报名信息,其他sheet表 是每个校运会运动项目学生的报名信息表。
单个的报名表截图如下:
作为试验,我们做了五个Excel表格,放在了项目文件下的 tables 文件夹:
注:Excel文件名无所谓(最好不要有中文和特殊字符)。
我们希望做成的汇总数据表如下:
主要思路及实现代码:
1、先获取目标文件路径下的所有Excel文件:
这里用的是 os 模块的 walk 方法来获取:
# 先遍历目录下文件
path = './tables' # 此处用的是相对路径(如自己试验,需注意自己的文件路径)
f = os.walk(path)
files = [] # xls 文件列表
# 获取目录下文件
for dir_path, dir_names, file_names in f:
for file in file_names:
# 筛选目录下xls格式文件
if '.xls' in file:
files.append(file)
print(files) # 测试获取的文件
# 打印结果:
# ['5.xls', '1.xls', '2.xls', '3.xls', '4.xls']
经过上面的代码,我们已经获取到了我们想要的Excel表格文件。
2、读取所有Excel表格数据:
分析: 因为我们要读取多个文件数据,每个文件的数据结构比较一致,后期还要进行数据汇总与统计工作。
所以在前期选好一个 数据结构来存储数据 ,是非常重要的。这里决定先设计一个包含列表的列表来存储数据,数据结构示意:
[[[第一行数据:学院班级信息],[第二行数据: 报名信息字段], [第三行数据:报名信息]…], [第二个表数据],[],…]
这里不用字典结构来存储数据,是为了后期统计数据方便。如果按照逻辑来说,用字典的键对应文件名或学院班级信息,值对应该班级报名信息更合理些。
读取数据也比较关键,先定义了一个读取单个表格数据的函数:
# 定义读取单个 excel 文件数据
def read_excel(name):
file_path = path + '/'+ name
work_book = xlrd.open_workbook(file_path)
sheet = work_book.sheet_by_index(0)
return sheet._cell_values[1:]
# 测试一下:
print(read_excel(files[0]))
# ------运行结果------
# [['学院:', '机械学院', '', '年级:', 2015.0, '专业:', '模具设计', ''],
# ['姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式'],
# ['阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0],
# ['阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0],
# ['阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0],
# ...
# ------运行结果------
可以看到,写的方法可以成功的读取到单个表格的数据(忽略数据内容…,人名太难想了…)。
有了这个方法读取所有表格的数据就很简单了,这里用的是列表推导式:
# 读取目录下所有数据
sign_data = [read_excel(name) for name in files]
print(sign_data) # 测试读取到的所有数据
# ------运行结果------
# [[['学院:', '机械学院', '', '年级:', 2015.0, '专业:', '模具设计', ''],
# ['姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式'],
# ['阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0],
# ['阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0],
# ['阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0],
# ['时迁', 150914034.0, '男', 22.0, '乒乓球', '否', '能', 15468081558.0],
# ['顾大嫂', 150914042.0, '女', 21.0, '羽毛球', '否', '能', 15509431558.0],
# ...
# ------运行结果------
3、按需求汇总数据:
在数据处理这一步,选择列表嵌套列表的数据结构优势就体现出来了:
# 按照汇总要求整理数据
summary_data = []
for data in sign_data:
for d in data[2:]:
# 在每条报名信息中插入学院、年级、专业信息
d.insert(0,data[0][6]) # 专业信息
d.insert(0,data[0][4]) # 年级信息
d.insert(0,data[0][1]) # 学院信息
summary_data.append(d)
print(summary_data) # 测试汇总数据
# ------运行结果------
# [['机械学院', 2015.0, '模具设计', '阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0],
# ['机械学院', 2015.0, '模具设计', '阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0],
# ['机械学院', 2015.0, '模具设计', '阮小七', 150914010.0, '男', 22.0, '1000米', '否', '能', 18953000549.0],
# ['机械学院', 2015.0, '模具设计', '时迁', 150914034.0, '男', 22.0, '乒乓球', '否', '能', 15468081558.0],
# ['机械学院', 2015.0, '模具设计', '顾大嫂', 150914042.0, '女', 21.0, '羽毛球', '否', '能', 15509431558.0],
# ...
# ------运行结果------
注:这里按汇总信息sheet表的要求,已为每条报名数据加上了学院、年级、专业信息,列表所有数据相当于是独立的,即与原来的每个文件已没有关系了。
这里还用代码获取了一下 汇总sheet 表里要用到的信息名称字段:
# 报名字段列表
sign_keys = sign_data[0][1]
# 汇总表格字段操作
summary_key = sign_keys[:]
summary_key.insert(0,'专业信息')
summary_key.insert(0,'年级信息')
summary_key.insert(0,'学院信息')
print(summary_key) # 测试汇总字段
# 打印结果
# ['学院信息', '年级信息', '专业信息', '姓名', '学号', '性别', '年龄', '参赛项目', '是否参加往届过校运会', '能否参加集训', '联系方式']
4、按照校运会运动项目统计报名信息:
1、获取校运会运动项目列表:
# 获取校运会运动项目清单
sports = []
for data in summary_data:
if data[7] not in sports:
sports.append(data[7])
print(sports) # 测试
# 打印结果:
# ['10000米', '400米', '1000米', '乒乓球', '羽毛球', '铅球', '跳高', '100米', '跳远', '游泳', '竞走']
因为我们没有所有运动项目的数据,所以需先获取所有报名 Excel 表格里的参赛项目信息。
2、按运动项目筛选报名信息:
选择字典来存储各个运动项目的报名信息:
# 按运动项目筛选报名信息
sport_data = {}
for sport in sports:
sport_data[sport] = []
for data in summary_data:
if sport == data[7]:
sport_data[sport].append(data)
print(sport_data) # 测试
# ------运行结果------
# {'10000米': [['机械学院', 2015.0, '模具设计', '阮小二', 150914031.0, '男', 23.0, '10000米', '否', '能', 15854441586.0],
# ['化学学院', 2015.0, '分析化学', '孙悟空', 150813031.0, '男', 19.0, '10000米', '否', '能', 15854891586.0],
# ['机械学院', 2016.0, '自动化', '鲁智深', 160814031.0, '男', 23.0, '10000米', '否', '能', 15854331586.0]],
# '400米': [['机械学院', 2015.0, '模具设计', '阮小五', 150914025.0, '男', 21.0, '400米', '否', '能', 17054661590.0],
# ['马克思学院', 2016.0, '思想政治教育', '张三', 160813025.0, '男', 20.0, '400米', '否', '能', 17054891586.0],
# ['马克思学院', 2016.0, '思想政治教育', '曾漂亮', 160813032.0, '女', 20.0, '400米', '否', '能', 17054891586.0],
# ...
# ------运行结果------
请忽略姓名…
5、将数据写入Excel表格
用 xlwt 模块新建一个 Excel 文件,创建 ‘汇总信息’ sheet表写入汇总信息,其他 sheet 写入相应运动项目报名者信息。
work_book = xlwt.Workbook()
sheet_0 = work_book.add_sheet('汇总信息')
sheet_0.write_merge(0,0,0,10,'xx大学校运会报名信息表')
# 写入汇总表格报名信息字段
for col,string in enumerate(summary_key):
sheet_0.write(1,col,string)
# 写入汇总数据
for row,ds in enumerate(summary_data):
for col,d in enumerate(ds):
sheet_0.write(row+2,col,d)
# 写入各个运动项目的报名信息sheet表
for sport,s_ds in sport_data.items():
# 增加sheet表
s_sheet = work_book.add_sheet(sport)
# 在sheet表中增加数据
s_sheet.write_merge(0,0,0,10,'%s参赛项目报名人员信息汇总' % sport)
for col, string in enumerate(summary_key):
s_sheet.write(1, col, string)
# 写入具体报名人员信息
for row,ds in enumerate(s_ds):
for col, d in enumerate(ds):
s_sheet.write(row + 2, col, d)
# 保存表格
work_book.save('summary_sign.xls')
这里的代码主要是利用 xlwt 模块写入数据,逻辑比较简单,直接看最后的文件截图吧。
新建的 summary_sign.xls 文件部分数据截图:
全部代码:
以下是该实例的全部代码:
import xlrd
import xlwt
import os
# 获取目录下文件
# 先遍历目录下文件
path = './tables' # 此处用的是相对路径(注意自己的文件路径)
f = os.walk(path)
files = [] # xls 文件列表
# 获取目录下文件
for dir_path, dir_names, file_names in f:
for file in file_names:
# 筛选目录下xls格式文件
if '.xls' in file:
files.append(file)
# 用 xlrd 读取Excel文件数据
# 定义读取单个 excel 文件数数据
def read_excel(name):
file_path = path + '/'+ name
work_book = xlrd.open_workbook(file_path)
sheet = work_book.sheet_by_index(0)
return sheet._cell_values[1:]
# 读取目录下所有数据
sign_data = [read_excel(name) for name in files]
# 按照汇总要求整理数据
summary_data = []
for data in sign_data:
for d in data[2:]:
# 在每条报名信息中插入学院、年级、专业信息
d.insert(0,data[0][6]) # 专业信息
d.insert(0,data[0][4]) # 年级信息
d.insert(0,data[0][1]) # 学院信息
summary_data.append(d)
# 报名字段列表
sign_keys = sign_data[0][1]
# 汇总表格字段操作
summary_key = sign_keys[:]
summary_key.insert(0,'专业信息')
summary_key.insert(0,'年级信息')
summary_key.insert(0,'学院信息')
# 获取校运会运动项目清单
sports = []
for data in summary_data:
if data[7] not in sports:
sports.append(data[7])
# 按运动项目筛选报名信息
sport_data = {}
for sport in sports:
sport_data[sport] = []
for data in summary_data:
if sport == data[7]:
sport_data[sport].append(data)
# 写入数据
work_book = xlwt.Workbook()
sheet_0 = work_book.add_sheet('汇总信息')
sheet_0.write_merge(0,0,0,10,'xx大学校运会报名信息表')
# 写入汇总表格报名信息字段
for col,string in enumerate(summary_key):
sheet_0.write(1,col,string)
# 写入汇总数据
for row,ds in enumerate(summary_data):
for col,d in enumerate(ds):
sheet_0.write(row+2,col,d)
# 写入各个运动项目的报名信息sheet表
for sport,s_ds in sport_data.items():
# 增加sheet表
s_sheet = work_book.add_sheet(sport)
# 在sheet表中增加数据
s_sheet.write_merge(0,0,0,10,'%s参赛项目报名人员信息汇总' % sport)
for col, string in enumerate(summary_key):
s_sheet.write(1, col, string)
# 写入具体报名人员信息
for row,ds in enumerate(s_ds):
for col, d in enumerate(ds):
s_sheet.write(row + 2, col, d)
# 保存表格
work_book.save('summary_sign.xls')
注:以上代码,很多信息其实未具体指定,如有哪些运动项目、班级信息、专业信息等。数据内容字段(如:学院信息, 年级信息, 专业信息…)这些都是直接从表格里获取的。也就是说 该代码的复用性是比较高的,换做其他报名信息的统计,稍微改动一下,应该就可以运行了 。
结尾:
以上就是本篇博客的全部内容,项目也不难,就100来行代码吧,想要原 Excel 表格文件来测试一下代码的朋友可私信、留言 ,感觉阅读。
【Python与Excel表格】专栏
着重介绍 Python xlwt、xlrd 等模块操作 Excel 表格文件的方法,也会搭配一些实例演练,强化所讲知识点的理解与运用。
感兴趣的朋友,可以点个关注或收藏。 创作不易,你的支持是我最大的动力,感谢 !