如何在Python中快速打开excel文件?

我现在使用PyExcelerator读取excel文件,但是速度非常慢。 由于我总是需要打开超过100MB的excel文件,因此只需要加载一个文件需要20多分钟的时间。

我需要的function是:

  • 打开Excel文件,select特定的表格,并将其加载到字典或列表对象中。
  • 有时:select特定的列,只加载具有特定值的特定列的整个行。
  • 读取密码保护的Excel文件。

而我现在使用的代码是:

book = pyExcelerator.parse_xls(filepath) parsed_dictionary = defaultdict(lambda: '', book[0][1]) number_of_columns = 44 result_list = [] number_of_rows = 500000 for i in range(0, number_of_rows): ok = False result_list.append([]) for h in range(0, number_of_columns): item = parsed_dictionary[i,h] if type(item) is StringType or type(item) is UnicodeType: item = item.replace("\t","").strip() result_list[i].append(item) if item != '': ok = True if not ok: break 

有什么build议么?

pyExcelerator似乎不被维护。 要编写xls文件,请使用xlwt,它是pyExcelerator的一个分支,具有错误修复和许多增强function。 pyExcelerator的(非常基本的)xls读取function从xlwt中被清除。 要读取xls文件,请使用xlrd。

如果加载一个100MB的xls文件需要20分钟,您必须使用一个或多个:慢速计算机,可用内存很less的计算机或较旧版本的Python。

pyExcelerator和xlrd都不能读取受密码保护的文件。

这是一个涵盖xlrd和xlwt的链接 。

免责声明:我是xlrd的xlrd和维护者的作者。

xlrd对于阅读文件来说相当不错,而xlwt对写作来说相当不错。 在我的经验中,都优于pyExcelerator。

你可以尝试在一个语句中预先分配列表的大小,而不是像这样一次追加一个项目(一个大的内存分配应该比许多小的分配快)

 book = pyExcelerator.parse_xls(filepath) parsed_dictionary = defaultdict(lambda: '', book[0][1]) number_of_columns = 44 number_of_rows = 500000 result_list = [] * number_of_rows for i in range(0, number_of_rows): ok = False #result_list.append([]) for h in range(0, number_of_columns): item = parsed_dictionary[i,h] if type(item) is StringType or type(item) is UnicodeType: item = item.replace("\t","").strip() result_list[i].append(item) if item != '': ok = True if not ok: break 

如果这样做可以提高性能,那么也可以尝试预先分配每个列表项的列数,然后通过索引分配它们,而不是一次追加一个值。 这是一个代码片段,它在一个初始值为0的单个语句中创build一个10×10二维列表:

 L = [[0] * 10 for i in range(10)] 

如此折叠到你的代码,它可能是这样的:

 book = pyExcelerator.parse_xls(filepath) parsed_dictionary = defaultdict(lambda: '', book[0][1]) number_of_columns = 44 number_of_rows = 500000 result_list = [[''] * number_of_rows for x in range(number_of_columns)] for i in range(0, number_of_rows): ok = False #result_list.append([]) for h in range(0, number_of_columns): item = parsed_dictionary[i,h] if type(item) is StringType or type(item) is UnicodeType: item = item.replace("\t","").strip() result_list[i,h] = item if item != '': ok = True if not ok: break 

与你的问题无关 :如果你想检查是否没有空string,那么你首先设置ok = True ,然后在内部循环( ok = ok and item != '' )中进行设置。 另外,你可以使用isinstance(item, basestring)来testing一个variables是否是string。

经过修改的版本

 for i in range(0, number_of_rows): ok = True result_list.append([]) for h in range(0, number_of_columns): item = parsed_dictionary[i,h] if isinstance(item, basestring): item = item.replace("\t","").strip() result_list[i].append(item) ok = ok and item != '' if not ok: break