前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python读取Excel文件sheet名性能优化

Python读取Excel文件sheet名性能优化

作者头像
Ewdager
发布2020-07-14 14:45:46
1K0
发布2020-07-14 14:45:46
举报
文章被收录于专栏:Gvoidy备份小站Gvoidy备份小站

原始版本

直接使用pandas读取整个Excel文件,再从中取列名。这种场景对于小的Excel文件还适用,但数据量上升到10M+时,取个sheet name26s之久。几乎无法忍受。

data = pandas.ExcelFile(file_url)
names = data.sheet_names

优化

查阅资料可知.xlsx文件是一个压缩格式的文件,可以直接通过zipfile读到sheet name等相关信息。所以写如下函数直接取sheet name

def get_sheet_details(file_path):
    sheets = []
    file_name = os.path.splitext(os.path.split(file_path)[-1])[0]
    # 用文件名创建一个临时目录
    directory_to_extract_to = file_name
    os.mkdir(directory_to_extract_to)

    # 提取xlsx文件,因为它只是一个zip文件
    zip_ref = zipfile.ZipFile(file_path, 'r')
    zip_ref.extractall(directory_to_extract_to)
    zip_ref.close()

    # 建立一个临时的workbook文件
    path_to_workbook = os.path.join(directory_to_extract_to, 'xl', 'workbook.xml')
    with open(path_to_workbook, 'r') as f:
        xml = f.read()
        dictionary = xmltodict.parse(xml)
        # 多个sheet
        if isinstance(dictionary['workbook']['sheets']['sheet'], list):
            for sheet in dictionary['workbook']['sheets']['sheet']:
                # 有些版本的sheet是@name有些是@sheetId
                if sheet["@name"]:
                    meta_sheet = sheet["@name"]
                else:
                    meta_sheet = sheet["@sheetId"]
                sheets.append(meta_sheet)
        # 单个sheet
        else:
            sheet_dict = dictionary['workbook']['sheets']['sheet']
            if sheet_dict["@name"]:
                sheets.append(sheet_dict["@name"])
            else:
                sheets.append(sheet_dict["@sheetId"])

    shutil.rmtree(directory_to_extract_to)
    f.close()
    return sheets

使用该种方法,读14M的文件仅需0.04s。(数据都没加载,当然和文件大小无关啦)

一个问题

该函数只能针对.xlsx文件进行解析,而低版本的.xls文件就直接报错了,因为.xls是一个二进制文件而不是压缩文件。所以要以另一种方式去解析sheet name。经过查阅相关资料,发现xlrd.open_workbookon_demand=True针对低版本的Excel文件可以只取列名而不加载数据。

if file_url[-3:] == 'xls':
    names = xlrd.open_workbook(file_url, on_demand=True).sheet_names()
else:
    names = get_sheet_details(file_url)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原始版本
  • 优化
  • 一个问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档