Python 使读取 Excel 文件更快

问题描述 投票:0回答:3

我制作了一个读取 Excel 文档并检查第一行是否包含“UPDATED”的脚本。如果是这样,它将整行写入具有相同选项卡名称的另一个 Excel 文档。

我的Excel文档有23张纸,每张纸有1000行,现在需要15分钟以上才能完成。有没有办法加快速度?

我正在考虑多线程或多处理,但我不知道哪个更好。

更新:我的程序运行了 15 分钟的事实是由只读模式引起的,当我删除它时,运行程序只花了 2 秒

import openpyxl
import os
from datetime import datetime

titles = ["Column1", "Column2", "Column3", "Column4", "Column5","Column6", "Column7", "Column8", "Column9", "Column10", "Column11", "Column12", "Column13", "Column14", "Column15", "Column16"]


def main():
    oldFilePath= os.getcwd() + "\oldFile.xlsx"
    newFilePath= os.getcwd() + "\newFile.xlsx"

    wb = openpyxl.load_workbook(filename=oldFilePath, read_only=True)
    wb2 = openpyxl.Workbook()

    sheets = wb.get_sheet_names()
    sheets2 = wb2.get_sheet_names()

    #removes all sheets in newFile.xlsx
    for sheet in sheets2:
        temp = wb2.get_sheet_by_name(sheet)
        wb2.remove_sheet(temp)

    for tab in sheets:
        print("Sheet: " + str(tab))
        rowCounter = 2

        sheet = wb[tab]
        for row in range(sheet.max_row):
            if sheet.cell(row=row + 1, column=1).value == "": #if cell is empty stop reading
                break
            elif sheet.cell(row=row + 1, column=1).value == "UPDATED":
                if tab not in sheets2:
                    sheet2 = wb2.create_sheet(title=tab)
                    sheet2.append(titles)

                for x in range(1, 17):
                    sheet2.cell(row=rowCounter, column=x).value = sheet.cell(row=row + 1, column=x).value

                rowCounter += 1

                sheets2 = wb2.get_sheet_names()

    wb2.save(filename=newFilePath)


if __name__ == "__main__":
    startTime = datetime.now()
    main()
    print("Script finished in: " + str(datetime.now() - startTime))
python excel python-3.x openpyxl
3个回答
2
投票

对于如此小的工作簿,没有必要使用只读模式,如果不明智地使用它,您自己就会导致问题。每次调用

ws.cell()
都会强制 openpyxl 再次解析工作表。

因此,要么停止使用只读模式,要么按照我在上一个问题中建议的方式使用

ws.iter_rows()

一般来说,如果您认为某些东西运行缓慢,您应该始终对其进行分析,而不是仅仅尝试某些东西并希望得到最好的结果。


1
投票

您应该看看一些很棒的多处理教程,例如: https://www.blog.pythonlibrary.org/2016/08/02/python-201-a-multiprocessing-tutorial/

此外,Python 文档将为您提供一些很好的示例: https://docs.python.org/3.6/library/multiprocessing.html

您应该特别注意使用池和队列等主题。

多处理将帮助您克服全局解释器锁的限制,因此这可能是提高性能的好方法。

调整 I/O 进程的性能可能是一个棘手的话题,因此您需要了解有关瓶颈的更多详细信息。如果您无法提高其性能,您可能会尝试寻找其他方法来获取相同的数据。


0
投票

我最近运行了一个关于将 Excel 文件加载到 Python 中的方法的基准测试。我发现在 Python 中从 Excel 文件加载数据的最快方法是使用 python-calamine

$ pip install python-calamine

这是我使用 python-calamine 将 Excel 加载到 Python 文件的代码:

import python_calamine

def iter_excel_calamine(file: IO[bytes]) -> Iterator[dict[str, object]]:
    workbook = python_calamine.CalamineWorkbook.from_filelike(file)  # type: ignore[arg-type]
    rows = iter(workbook.get_sheet_by_index(0).to_python())
    headers = list(map(str, next(rows)))
    for row in rows:
        yield dict(zip(headers, row))

该函数返回行的迭代器。它还维护 Excel 文件中的类型。

这里是我使用几个 python 包和方法的结果总结:

方法 时间(秒) 类型 版本
熊猫 32.98 是的 2.1.3
Tablib 28.52 是的 3.5.0
打开pyxl 35.62 是的 3.1.2
Openpyxl(只读) 24.79 是的 3.1.2
自由办公室 15.27 没有 7.5.8.2
DuckDB(sql) 11.36 是的 0.9.2
DuckDB(执行) 5.73 没有 0.9.2
炉甘石(蟒蛇炉甘石) 3.58 是的 0.22.1 (0.1.7)

完整的代码示例和基准测试可以在这里找到:

https://hakibenita.com/fast-excel-python#reading-excel-using-calamine

© www.soinside.com 2019 - 2024. All rights reserved.