我制作了一个读取 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))
对于如此小的工作簿,没有必要使用只读模式,如果不明智地使用它,您自己就会导致问题。每次调用
ws.cell()
都会强制 openpyxl 再次解析工作表。
因此,要么停止使用只读模式,要么按照我在上一个问题中建议的方式使用
ws.iter_rows()
。
一般来说,如果您认为某些东西运行缓慢,您应该始终对其进行分析,而不是仅仅尝试某些东西并希望得到最好的结果。
您应该看看一些很棒的多处理教程,例如: 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 进程的性能可能是一个棘手的话题,因此您需要了解有关瓶颈的更多详细信息。如果您无法提高其性能,您可能会尝试寻找其他方法来获取相同的数据。
我最近运行了一个关于将 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