专栏首页Gvoidy备份小站Python读取Excel文件sheet名性能优化

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

原始版本

直接使用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)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 经典排序算法 Python 实现

    在操作过程中维护一个排好序的片段,初始只包含一个元素。每次从未排序的片段取出一个元素插入正确的位置。时间复杂度为O(n²)

    Ewdager
  • 从零开始学Laravel

    安装好WAMP环境后,在wampmanager.ini文件中将PHP版本更改为php7,查看php版本可以通过phpinfo()函数查看。 ,下载好后解压至Ap...

    Ewdager
  • 常见设计模式 Python 实现

    单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类 “类 (计算机科学)”)必须保证只有一个实例存在。许多时候整个系统只需要拥有一...

    Ewdager
  • Python xlrd模块导入过程及常用操作

    砸漏
  • PHP使用PhpSpreadsheet操作Excel实例详解

    本文实例讲述了PHP使用PhpSpreadsheet操作Excel。分享给大家供大家参考,具体如下:

    砸漏
  • Python读取CSV和Excel

    逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本...

    Minerva
  • 最全总结 | 聊聊 Python 办公自动化之 Excel(上)

    但是,经常会遇到一些重复繁琐的事情,这时候手工操作显得效率极其低下;通过 Python 实现办公自动化变的很有必要

    AirPython
  • Laravel-Excel导出功能文档

    可以在闭包中修改一些属性,很多属性可在配置文件中设置默认值 config/excel.php

    Tayloryu
  • 接口测试框架——第二篇

    用户2149234
  • Python openpyxl : Ex

    通过调用方法load_workbook(filename)进行文件读取,该方法中还有一个read_only参数用于设置文件打开方式,默认为可读可写,该方法最终将...

    py3study

扫码关注云+社区

领取腾讯云代金券