解决使用Pandas 读取超过65536行的Excel文件问题
作者:Python野路子 发布时间:2022-03-28 09:17:29
场景
今天需要合并天猫订单数据,由于前期6.18活动有很多数据需要处理,将几个月份合并一起,结果报错。
问题分析
Excel 文件的格式曾经发生过一次变化,在 Excel 2007 以前,使用扩展名为 .xls 格式的文件,这种文件格式是一种特定的二进制格式,最多支持 65,536 行,256 列表格。从 Excel 2007 版开始,默认采用了基于 XML 的新的文件格式 .xlsx ,支持的表格行数达到了 1,048,576,列数达到了 16,384。需要注意的是,将 .xlsx 格式的文件转换为 .xls 格式的文件时,65536 行和 256 列之后的数据都会被丢弃。
Pandas 读取 Excel 文件的引擎是 xlrd , xlrd 虽然同时支持 .xlsx 和 .xls 两种文件格式,但是在源码文件 xlrd/sheet.py 中限制了读取的 Excel 文件行数必须小于 65536,列数必须小于 256。
if self.biff_version >= 80:
self.utter_max_rows = 65536
else:
self.utter_max_rows = 16384
self.utter_max_cols = 256
这就导致,即使是 .xlsx 格式的文件, xlrd 依然不支持读取 65536 行以上的 Excel 文件(源码中还有一个行数限制是 16384,这是因为 Excel 95 时代, xls 文件所支持的最大行数是 16384)。
解决办法
openpyxl 是一个专门用来操作 .xlsx 格式文件的 Python 库,和 xlrd 相比它对于最大行列数的支持和 .xlsx 文件所定义的最大行列数一致。
首先安装 openpyxl :
pip install openpyxl
Pandas 的 read_excel 方法中,有 engine 字段,可以指定所使用的处理 Excel 文件的引擎,填入 openpyxl ,再读取文件就可以了。
import os
import pandas as pd
# 将文件读取出来放一个列表里面
pwd = '1' # 获取文件目录
# 新建列表,存放文件名
file_list = []
# 新建列表存放每个文件数据(依次读取多个相同结构的Excel文件并创建DataFrame)
dfs = []
for root,dirs,files in os.walk(pwd): # 第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。
for file in files:
file_path = os.path.join(root, file)
file_list.append(file_path) # 使用os.path.join(dirpath, name)得到全路径
df = pd.read_excel(file_path) # 导入xlsx文件,将excel转换成DataFrame
dfs.append(df)
# 将多个DataFrame合并为一个
df = pd.concat(dfs)
# 数据输出,写入excel文件,不包含索引数据
# 数据写入 Excel,需要首先安装一个 engine,由 engine 负责将数据写入 Excel,pandas 使用 openpyx 或 xlsxwriter 作为写入引擎。
df.to_excel('test\\1.xlsx', index=False,engine='openpyxl') # 导出 Excel,一般不需要索引,将 index 参数设为 False
补充知识:python使用xlrd读取excel数据作为requests的请求参数,并把返回的数据写入excel中
实现功能:
从excel中的第一列数据作为post请求的数据,数据为json格式;把post返回的结果写入到excel的第二列数据中,并把返回数据与excel中的预期结果做比较,如果与预期一致则在案例执行结果中写入成功,否则写入失败。
每一行的数据都不一样,可实现循环调用
# !/usr/bin/env python
# -*- coding:utf-8 -*-
#import xlwt #这个专门用于写入excel的库没有用到
import xlrd
from xlutils.copy import copy
import requests
import json
old_excel = xlrd.open_workbook('excel.xls')
sheet = old_excel.sheets()[0]
url = 'http://10.1.1.32:1380/service/allocFk2'
headers = {'Content-Type': 'application/json'}
i = 0
new_excel = copy(old_excel)
for row in sheet.get_rows():
data = row[0].value
response = requests.post(url=url, headers=headers, data=data)
text = response.text
#使用json.loads可以把Unicode类型,即json类型转换成dict类型
text = json.loads(text)["returnMsg"] #屏蔽这行代码即可把返回的完整数据写入文件中
ws = new_excel.get_sheet(0)
ws.write(i,1,text)
new_excel.save('excel.xls')
old_excel = xlrd.open_workbook('excel.xls')
new_excel = copy(old_excel)
i = i+1
执行前的excel格式:
发送报文 | 返回报文 | 校验字符 | 案例执行结果 |
{ "projectId" :"0070", "projectAllocBatch" :"1", "serviceCode" :"GT012", "seqNo" :"180800272201GT51286712", "tranTimeStamp" :"20180817102244", "sign" :"2dbb89a6bd86b2af1ff6a76c35c05284" } | 交易失败 | ||
{ "projectId" :"0070", "projectAllocBatch" :"1", "serviceCode" :"GT012", "seqNo" :"180800272201GT51286713", "tranTimeStamp" :"20180817102244", "sign" :"2dbb89a6bd86b2af1ff6a76c35c05284" } | 交易失败 | ||
{ "projectId" :"0070", "projectAllocBatch" :"1", "serviceCode" :"GT012", "seqNo" :"180800272201GT51286713", "tranTimeStamp" :"20180817102244", "sign" :"2dbb89a6bd86b2af1ff6a76c35c05284" } | 交易成功 |
执行后的结果:
调试过程中遇到的问题:
1、一开始在for循环的最后没有增加这两行代码
old_excel = xlrd.open_workbook('excel.xls')
new_excel = copy(old_excel)
这样的话new_excel永远都是一开始获取到的那一个,只会把最后一个循环返回的结果写入文件,因为之前的全部都被一开始获取的那个old_excel给覆盖了,所以每次执行完写入操作以后都要重新做一次copy操作,这样就能保证new_excel是最新的。
2、注意执行程序之前要把excel关闭,否则会报错
来源:https://www.jianshu.com/p/af19d37586a9


猜你喜欢
- 准备我测试使用的Python版本为2.7.10,如果你的版本是Python3.5的话,这里就不太适合了。 使用Speech API原理我们的
- 背景当我慢慢的开在高速公路上,宽敞的马路非常的拥挤!这时候我喜欢让百度导航的小度给我讲笑话,但她有点弱,每次只能讲一个。百度号称要发力人工智
- pycharm创建sql文件及模板创建模板pycharm默认新建文件选项中没有sql文件,每次通过文件末尾添加.sql识别文件格式很麻烦。可
- Flask解决跨域1、下载flask_cors包pip install flask-cors2、使用flask_cors的CORS代码示例f
- 大家都知道搜索引擎比较喜欢H1。在SEO中H1也是很基础也很重要的一步。但有些时候为了界面风格的原因,很多标题性的文字做成了图片。大多数情况
- 先来看段mysql查询文章回复语句:#查询文章回复-- ------------------------------ Procedure s
- 前言存储过程(Stored Procedure):一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过
- python-opencv3.0新增了一些比较有用的 * 算法,这里根据官网示例写了一个 * 类程序只能运行在安装有opencv3.0以上版
- set oSQLServer =server.createobject("SQLDMO.SQLServer"
- 介绍Redis是一个开源的基于内存也可持久化的Key-Value数据库,采用ANSI C语言编写。它拥有丰富的数据结构,拥有事务功能,保证命
- 前言:决策树是梯度提升机和随机森林的基本构建块,在学习这些模型的工作原理和模型可解释性时,可视化决策树是一个非常有帮助。不过,当前的可视化包
- 本文实例讲述了python使用PyGame绘制图像并保存为图片文件的方法。分享给大家供大家参考。具体实现方法如下:''
- 写过稍微大型一点 ASP 的人都知道,Session 这个对象真是好用,它可以用来记录使用者私有的资料变量,既安全又方便。但是你真的知道 S
- js 中判断某个元素是否存在于某个 js 数组中,相当于 php 语言中的 in_array 函数。Array.prototype.S=St
- --按日 select sum(consume),day([date]) from consume_record where year([d
- # os 模块os.sep 可以取代操作系统特定的路径分隔符。windows下为 '\\'os.name 
- 目前有好几种方法可以将python文件打包成exe应用程序文件,例如py2exe,pyinstaller等,比较下来,还是觉得pyinsta
- 前言:作为一个.NET开发者而已,有着宇宙最强IDE:Visual Studio加持,让我们的开发效率得到了更好的提升。我们不需要担心环境变
- 本文实例讲述了GO语言实现简单的目录复制功能。分享给大家供大家参考。具体实现方法如下:创建一个独立的 goroutine 遍历文件,主进程负
- Python中函数参数的定义主要有四种方式:1. F(arg1,arg2,…)这是最常见的定义方式,一个函数可以定义任意个参数,每个参数间用