如何在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