我有一个程序正在从Excel电子表格中读取一些数据(一个小数据:约10张,每张约100个单元格),进行一些计算,然后将输出写入电子表格中的单元格。
程序运行很快,直到我修改为将其输出写入与读取输入的Excel文件相同的位置。以前我正在生成一个新的电子表格,然后手动将输出复制到原始文件中。
修改后,脚本的运行时间从几秒钟跳到大约7分钟。我运行cProfile来调查并获得此输出,按累计运行时间排序:
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.001 0.001 440.918 440.918 xlsx_transport_calc.py:1(<module>)
1 0.000 0.000 437.926 437.926 excel.py:76(load_workbook)
1 0.000 0.000 437.924 437.924 excel.py:161(_load_workbook)
9 0.000 0.000 437.911 48.657 worksheet.py:302(read_worksheet)
9 0.000 0.000 437.907 48.656 worksheet.py:296(fast_parse)
9 0.065 0.007 437.906 48.656 worksheet.py:61(parse)
9225 45.736 0.005 437.718 0.047 worksheet.py:150(parse_column_dimensions)
9292454 80.960 0.000 391.640 0.000 functools.py:105(wrapper)
9292437 62.181 0.000 116.213 0.000 cell.py:94(get_column_letter)
18585439 20.881 0.000 98.832 0.000 threading.py:214(__exit__)
18585443 58.912 0.000 86.641 0.000 threading.py:146(acquire)
18585443 56.600 0.000 77.951 0.000 threading.py:186(release)
9293461/9293452 22.317 0.000 22.319 0.000 {method 'join' of 'str' objects}
37170887 15.795 0.000 15.795 0.000 threading.py:63(_note)
21406059 13.460 0.000 13.460 0.000 {divmod}
37170888 12.853 0.000 12.853 0.000 {thread.get_ident}
18585447 12.589 0.000 12.589 0.000 {method 'acquire' of 'thread.lock' objects}
21408493 9.948 0.000 9.948 0.000 {chr}
21441151 8.323 0.000 8.323 0.000 {method 'append' of 'list' objects}
18585446 7.843 0.000 7.843 0.000 {method 'release' of 'thread.lock' objects}
...
...
...
脚本中的相关代码:
...
from openpyxl import load_workbook
import pandas as pd
...
xlsx = 'path/to/spreadsheet.xlsx'
...
def loadxlsx(fname, sname, usecols=None):
with pd.ExcelFile(fname) as ef:
df = ef.parse(sheetname=sname)
if usecols:
return [df.values[:,col] for col in usecols]
else:
return [df.values[:,col] for col in range(df.shape[1])]
...
data = loadxlsx('path/to/spreadsheet.xlsx')
...
<do computations>
...
book = load_workbook(xlsx)
<write data back to spreadsheet>
...
因此,根据cProfile输出,罪魁祸首出现在对load_workbook
的调用中。除了那个观察之外,我有点困惑。为什么有9000个调用parse_column_dimensions
和1800个调用各种线程函数?还有900万次拨打get_column_letter
?
这是我第一次分析任何python脚本,所以我不确定这个输出是否正常......但它似乎有一些奇怪的部分。
任何人都可以了解这里可能发生的事情吗?
答案 0 :(得分:0)
我不知道Pandas代码中发生了什么,但是通话次数是错误的。如果您尝试使用openpyxl打开文件并修改单元格,那么它应该快得多,所以看起来有一些不必要的循环。