Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中快速打开excel文件?_Python_Excel - Fatal编程技术网

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

如何在Python中快速打开excel文件?,python,excel,Python,Excel,我现在用它来读取excel文件,但速度非常慢。由于我总是需要打开超过100MB的excel文件,所以只加载一个文件需要20多分钟 我需要的功能是: 打开Excel文件,选择特定表,并将其加载到Dict或List对象中 有时:选择特定列并仅加载特定值中包含特定列的整行 读取受密码保护的Excel文件 我现在使用的代码是: book = pyExcelerator.parse_xls(filepath) parsed_dictionary = defaultdict(lambda: '', bo

我现在用它来读取excel文件,但速度非常慢。由于我总是需要打开超过100MB的excel文件,所以只加载一个文件需要20多分钟

我需要的功能是:

  • 打开Excel文件,选择特定表,并将其加载到Dict或List对象中
  • 有时:选择特定列并仅加载特定值中包含特定列的整行
  • 读取受密码保护的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

有什么建议吗?

非常适合阅读文件和写作。根据我的经验,两者都优于pyExcelerator。

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

如果这样做可以显著提高性能,您还可以尝试使用列数预先分配每个列表项,然后按索引分配它们,而不是一次追加一个值。下面是一个片段,它在一条初始值为0的语句中创建一个10x10的二维列表:

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

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

如果加载一个100MB xls文件需要20分钟,那么您必须使用一台或多台计算机:速度较慢的计算机、可用内存非常少的计算机或较早版本的Python

PyExcelator和xlrd均不读取受密码保护的文件

给你


免责声明:我是xlrd的作者,也是xlwt的维护者。

与您的问题无关。:如果您试图检查所有列是否为空字符串,那么您首先设置
ok=True
,然后在内部循环中执行此操作(
ok=ok and item!='
)。另外,您可以使用
isinstance(item,basestring)
测试变量是否为字符串

修订版

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

我最近建立了一个可能感兴趣的图书馆:。它基本上尝试像Python处理普通文件一样“流化”Excel文件,因此,当您只需要一部分数据时(特别是当数据接近文件开头时),速度非常快。

您尝试过其他库吗?(我没有这方面的技术知识,我只是感兴趣)是的,我试过了,但这些都没有写xls的功能。读完大xls后,我必须做一些计算,并将结果保存到小xls中。@FelixYan:好的,很高兴知道,希望你得到一些好的答案!对于您可以使用的编写部分,或者,如果您只是编写值,您可以使用(可以很容易地导入Excel)。这20分钟是否只包括PyExcelator.parse_xls(),或者您正在计算自己的后续代码?问题是,我不知道xls文件的大小。因此,
行数
变量只是我猜想的最大大小。所以预分配会占用太多内存吗?您知道列数,但不知道行数?列数是固定的吗?无论如何,这可能值得一试。对两种不同算法的子集进行性能比较,比如1000行。你可以从那里测量。谢谢。当然值得一试:P.你是对的,列数是固定的,我不知道行数。你可以通过迭代直到
item!=''来确定行数并仅递增一个计数器。这将是作业前的一个额外步骤,但这将确定上限。你可以做的另一件事是使用性能监控应用程序查看流程。注意内存增长,尤其是页面错误。页面错误会扼杀像您这样的嵌套循环,而预分配是解决这些问题的好方法。谢谢您,我将尝试这两种方法。事实上,我使用的是AMD Phenom II X4 945,带有4G RAM和2G或更多内存,其中包括x86_64 Linux操作系统中的免费、SSD和Python 2.7。其他地方的阅读过程可能会更慢。谢谢!我对
类型(item)是StringType或类型(item)是UnicodeType
感到不舒服已经有这么长时间了!但是我不认为
ok=ok和item!=''之后很容易阅读,只是有点粗糙:)
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