Python 使读取 Excel 文件更快
Python make reading a Excel file faster
我制作了一个读取 Excel 文档的脚本,然后检查第一行是否包含 "UPDATED"。如果是这样,它会将整行写入另一个具有相同选项卡名称的 Excel 文档。
我的 Excel 文档是 23 sheet 秒,每个 sheet 有 1000 行,现在完成这个需要超过 15 分钟。有没有办法加快速度?
我在考虑多线程或多处理,但我不知道哪个更好。
更新:我的程序 运行 需要 15 分钟的事实是 READ-ONLY 模式引起的,当我删除它时,程序 运行 只需要 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))
您应该看看一些很棒的多处理教程,例如:
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 进程的性能可能是一个棘手的话题,因此您需要找出有关瓶颈的更多详细信息。如果您无法提高其性能,您可能会尝试寻找其他方法来获取相同的数据。
对于如此小的工作簿,没有必要使用 read-only 模式,不明智地使用它是您自己造成问题的原因。每次调用 ws.cell()
都会强制 openpyxl 再次解析工作表。
所以,要么你停止使用 read-only 模式,要么按照我在你上一个问题中建议的那样使用 ws.iter_rows()
。
一般来说,如果您认为某些东西 运行 很慢,您应该始终对它进行分析,而不是仅仅尝试一些东西并希望获得最好的结果。
我制作了一个读取 Excel 文档的脚本,然后检查第一行是否包含 "UPDATED"。如果是这样,它会将整行写入另一个具有相同选项卡名称的 Excel 文档。
我的 Excel 文档是 23 sheet 秒,每个 sheet 有 1000 行,现在完成这个需要超过 15 分钟。有没有办法加快速度?
我在考虑多线程或多处理,但我不知道哪个更好。
更新:我的程序 运行 需要 15 分钟的事实是 READ-ONLY 模式引起的,当我删除它时,程序 运行 只需要 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))
您应该看看一些很棒的多处理教程,例如: 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 进程的性能可能是一个棘手的话题,因此您需要找出有关瓶颈的更多详细信息。如果您无法提高其性能,您可能会尝试寻找其他方法来获取相同的数据。
对于如此小的工作簿,没有必要使用 read-only 模式,不明智地使用它是您自己造成问题的原因。每次调用 ws.cell()
都会强制 openpyxl 再次解析工作表。
所以,要么你停止使用 read-only 模式,要么按照我在你上一个问题中建议的那样使用 ws.iter_rows()
。
一般来说,如果您认为某些东西 运行 很慢,您应该始终对它进行分析,而不是仅仅尝试一些东西并希望获得最好的结果。