使用Python,Pandas和openpyxl加载的小Excel电子表格非常慢

时间:2015-02-02 18:46:31

标签: python excel pandas openpyxl

我有一个程序正在从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>
...

因此,根据cPro​​file输出,罪魁祸首出现在对load_workbook的调用中。除了那个观察之外,我有点困惑。为什么有9000个调用parse_column_dimensions和1800个调用各种线程函数?还有900万次拨打get_column_letter

这是我第一次分析任何python脚本,所以我不确定这个输出是否正常......但它似乎有一些奇怪的部分。

任何人都可以了解这里可能发生的事情吗?

1 个答案:

答案 0 :(得分:0)

我不知道Pandas代码中发生了什么,但是通话次数是错误的。如果您尝试使用openpyxl打开文件并修改单元格,那么它应该快得多,所以看起来有一些不必要的循环。