excel表格_excel函数公式大全_execl从入门到精通
Python利用openpyxl处理Excel文件(实战项目—人口统计)2024-03-23 07:14:39
之前,学习了两章关于openpyxl的基础知识,通过这些还不能了解openpyxl的强大作用。今天,带领大家通过一个实战项目认识openpyxl的强大之处,项目来自《Python编程快速上手—让繁琐工作自动化》一书,并对书中的例子进行了些许改动和扩充,本文旨在提供一种通过openpyxl处理大量Excel数据并进行数据统计的方法。项目数据来自网站(http://nostarch.com/automatestuff/),读者可以自行下载。
一、实例
有一个Excel电子表格,表格内的数据统计了20XX年某国人口普查数据,表格有四列,分别是普查区(一个地理区域,为人口普查而定义)区域编码、该区域所属州的简称、该区域所属县的名称、该区域的人口数量,表格中每一行表示一个人口普查区。现在要求统计该年度该国家的总人口、每个县的人口以及每个县里面包含的普查区的个数,并把这些内容写入工作簿的另一个工作表中。表格一共有7万多行数据。数据表结构如下图所示。
待处理的Excel表结构二、实例分析
该实例通过Excel筛选功能或者公式解决,对于一个熟练操作Excel的苦逼文员,可能需要1到n个小时来解决该问题,通过Excel公式解决该问题也较为繁琐。但是,如果我们利用openpyxl来统计该数据的话,只需要几秒钟就可以搞定了。下面我们分析解决问题的几个重点环节……
(一)需要打开该Excel文件并定位到具体的工作表,使用openpyxl.load_Workbook()、ws.get_sheet_by_name()函数;
(二)确定返回统计信息的数据结构,这里我们使用Python中的字典类型,popResult = {}。首先分析,每个县里面我们需要统计两个参数:”普查区数量”和“县的总人口”,于是,得到每个县的数据结构为:“县名称”:{“普查区数量”:n,”人口”:m},每个州里面有n多个县,我们最后统计的字典结构应该是这样的:popResult = {“州名称”:{“县名称”:{“普查区数量”:n,”县人口数”:m},……},……}。如果能理清这个数据结构,基本就算完成了一半任务。
(三)利用for循环遍历每一行数据,将每一行数据统计到popResult字典中;
(四)按照相关要求将结果写入本地Excel文件中。这一过程有个难点,就是如果直接遍历字典的话,字典结构比较复杂,会嵌套多个for循环,使得程序可读性变差,因此,我们将插入表格的每一行数据变成一个列表,然后循环遍历,通过列表的形式比较方便插入。所以,这一步我们转变了一次数据结构,使得问题得以方便解决。
三、编程解决问题
废话不说,直接上代码。
import openpyxl
popResult = {}
resultList = []
listItem = []
wb = openpyxl.load_workbook("population.xlsx")
# 只有一张表,用这种方式直接获取
ws = wb.active
# range()计算边界不含右边界,所以加1
for row in range(2, ws.max_row + 1):
city = ws['B' + str(row)].value
country = ws["C" + str(row)].value
population = ws["D" + str(row)].value
# 此处避免出现异常,因此使用setdefault
popResult.setdefault(city, {})
popResult[city].setdefault(country, {"area":0,"population":0})
# 统计区域数量和人口数量
popResult[city][country]["area"] += 1
popResult[city][country]["population"] += population
# for循环将得到的字典popResult转化为列表形式resultList,便于遍历写入countSheet表中
for city, country_info in popResult.items():
for country, info in country_info.items():
listItem.append(city)
listItem.append(country)
listItem.append(info['area'])
listItem.append(info["population"])
resultList.append(listItem)
# 置空便于下次循环
listItem = []
# 获得写入表countSheet的行数
numberRow = 0
for key, value in popResult.items():
numberRow += len(value)
print(numberRow)
# 然后将popResult写入另一个表中
countSheet = wb.create_sheet(index=1, title="统计结果")
# 直接将表头写入工作表
countSheet['A1'].value = "市"
countSheet['B1'].value = "县"
countSheet['C1'].value = "区域数量"
countSheet['D1'].value = "人口数量"
# 得到result_list
for row in range(2, numberRow + 1):
# 表格从第二行开始插入,而列表从index=0开始循环
countSheet['A' + str(row)] = resultList[row-2][0]
countSheet['B' + str(row)] = resultList[row-2][1]
countSheet['C' + str(row)] = resultList[row-2][2]
countSheet['D' + str(row)] = resultList[row-2][3]
# 保存修改,没有这一步countSheet表没有保存
wb.save("population.xlsx")
最终结果应该是这样的。
最终结果展示四、结果展望
一是不一定要将字典类型的数据结构转化为列表类型,如果数据量过大,这种转化既浪费时间,又可能得不到结果(死机啦),所以直接遍历字典或者引入yield也是不错的办法,我们将在以后探讨这个问题;
二是该程序提供了利用openpyxl进行Excel数据统计的一般方法。难点在于,如何构造一种或多种数据结构作为中介,来传递数据。
三是数据统计表中对于相同的市的单元格可以通过程序直接进行合并,这在以后的学习中再进行探讨。
可爱的python未完待续!
标签: Excel中如何统计户内人口数