python - openpyxl 在只读模式下真的很慢!!如何改进我的脚本?
问题描述
我写了一个简单的例子。此脚本读取一个 excel 文件并仅从其中复制第一列中存在列表“ls”中指定的字符串之一的行。复制的行将粘贴到另一个 excel 文件中。在我的代码下方:
from datetime import datetime
import openpyxl
print("Current Time =", datetime.now().strftime("%H:%M:%S"))
src_wb = openpyxl.load_workbook("C:\\Users\\Admin\\Desktop\\database.xlsx")
print("Current Time =", datetime.now().strftime("%H:%M:%S"))
print("\n\n")
src_ws = src_wb[src_wb.sheetnames[0]]
dst_wb = openpyxl.Workbook()
dst_ws = dst_wb.active
dst_ws.title = "TEST"
dst_row_id, src_row_id = 0, 0
ls = ["ciao", "hola", "hello"]
my_column_id = 1
for row in src_ws.rows:
src_row_id += 1
#print("Current Time =", datetime.now().strftime("%H:%M:%S"))
for element in ls:
if src_ws.cell(src_row_id, my_column_id).value == element:
dst_row_id += 1
dst_column_id = 0
for cell in row:
dst_column_id += 1
dst_cell = dst_ws.cell(dst_row_id,column=dst_column_id)
dst_cell.value = cell.value
break
dst_wb.save("test.xlsx")
dst_wb.close()
在输出下方:
λ python stack.py
Current Time = 19:36:38
Current Time = 19:37:20 <- after this point the script is quite fast
这段代码效果很好,但是当我的源 excel 文件很重时,该指令src_wb = openpyxl.load_workbook("C:\\Users\\Admin\\Desktop\\database.xlsx")
需要很多次。在我的示例中,“database.xlsx”文件有177137 行和14 列。打开它,openpyxl 需要 42 秒,但是当它必须读取行时,它似乎相当快。
openpyxl.load_workbook("C:\\Users\\Admin\\Desktop\\database.xlsx", read_only = True
为了改善这种情况,我尝试使用“只读”模式(慢(它太慢了,完成任务需要几个小时!)见下面的输出:
λ python stack.py
Current Time = 19:37:47
Current Time = 19:37:52 <-- after this point the script is very slow
如何提高只读模式下的脚本性能?或者也许以另一种方式,我不知道..根据您的经验,改进我的代码的最佳解决方案是什么?
@Daniel Ocando:我的 excel 文件由简单的字符串组成。下面是一个例子:
解决方案
您提供的代码具有三个嵌套的 for 循环(这通常意味着代码具有O(n3)
时间复杂度)。我设法删除了其中一个 for 循环,因此将时间复杂度降低到O(n2)
.
您可以利用集合通常比有关成员资格测试的列表更快的ls = ["ciao", "hola", "hello"]
优势,您可以将列表更改为set
.
最后,您可以利用write_only 模式来尝试加快写入速度。
考虑到单元格仅包含带有简单单词的字符串,您可以尝试以下代码并检查性能是否有所提高:
from datetime import datetime
import openpyxl
def get_list(row):
list_for_row_values = []
for cell in row:
list_for_row_values.append(cell.value)
return list_for_row_values
print("Current Time =", datetime.now().strftime("%H:%M:%S"))
src_wb = openpyxl.load_workbook("C:\\Users\\Admin\\Desktop\\database.xlsx", read_only=True)
print("Current Time =", datetime.now().strftime("%H:%M:%S"))
print("\n\n")
src_ws = src_wb[src_wb.sheetnames[0]]
dst_wb = openpyxl.Workbook(write_only=True)
dst_ws = dst_wb.create_sheet()
ls = ("ciao", "hola", "hello")
for row in src_ws.rows:
if(row[0].value) in ls:
list_for_row_values = get_list(row)
dst_ws.append(list_for_row_values)
dst_wb.save("test.xlsx")
推荐阅读
- django - Django:在日期时间字段上按日期分组
- html - 悬停时未打开引导子菜单
- apache-spark - 来自 ALS 模型的预测聚合 - SPARK 协作过滤
- arrays - 操作 Import-Csv 对象并逐行导出到文本文件
- ios - 如何混淆 Cordova 混合应用程序的 Objective C 代码?
- json - Power BI 自定义视觉对象 - 强制有向图 API 错误
- c# - 将二进制数据保存到表中时,我得到 NULL
- javascript - 如果字段有任何数据,应该看到添加按钮?onkeyup 功能不会每次都触发。我的目的是创建一个待办事项列表
- c# - AspNetCore Web Api 微软账户认证
- continuous-integration - Gitlab runner 使用共享运行器在 master 分支中运行我的 ci 部署