Python 一种大阵列的RAM错误

Python 一种大阵列的RAM错误,python,Python,我需要随机得到一行的数字,然后把每一行放到另一个数组中,然后得到一列的数字 我有一个大文件,超过400米。在该文件中,有13496*13496个数字,表示13496行和13496列。我想把它们读入数组。 这是我的代码: _L1 = [[0 for col in range(13496)] for row in range(13496)] _L1file = open('distanceCMD.function.txt') while (i<13496): print "i="+st

我需要随机得到一行的数字,然后把每一行放到另一个数组中,然后得到一列的数字

我有一个大文件,超过400米。在该文件中,有13496*13496个数字,表示13496行和13496列。我想把它们读入数组。 这是我的代码:

_L1 = [[0 for col in range(13496)] for row in range(13496)]
_L1file = open('distanceCMD.function.txt')
while (i<13496):
    print "i="+str(i)
    _strlf = _L1file.readline()
    _strlf = _strlf.split('\t')
    _strlf = _strlf[:-1]
    _L1[i] = _strlf
    i += 1
_L1file.close()
\u L1=[[0表示范围内的列(13496)]表示范围内的行(13496)]
_L1file=open('distanceCMD.function.txt')

而(i您可能希望以另一种方式处理您的问题。逐行处理文件。我认为不需要将整个大文件存储到数组中。否则,您可能希望告诉我们您实际尝试执行的操作

for line in open("400MB_file"):
     # do something with line.

例外情况:

当一个操作用完时引发 记忆但情况可能仍然存在 拯救(通过删除某些对象)。 关联的值是一个字符串 表示什么类型的(内部) 操作内存不足。请注意 因为潜在的内存 管理架构(C的malloc() 函数),解释器可能无法 始终能够完全恢复 从这种情况来看,它仍然存在 引发异常以使堆栈 可打印回溯,以防 逃跑计划是原因


至少在您的情况下,将整个文件读入内存似乎不是一个可行的选择。

这是一个简单的例子,说明您的程序需要的内存比计算机可用的内存多。13496x13496个元素的数组需要182142016个“单元”,其中一个单元至少是一个字节(如果存储字符)我甚至没有考虑特定运行时的数组元数据,尽管这对于一个简单数组来说通常是一个很小的开销

假设每个数组元素只是一个字节,计算机需要大约180MB的RAM才能将其全部存储在内存中。试图处理它可能是不切实际的

您需要以不同的方式思考问题;正如前面提到的,逐行方法可能是一个更好的选择。或者可能以较小的单位(可能是10x10或100x100)处理网格,并聚合结果。或者可能问题本身可以用不同的形式表示,从而避免处理整个网格共…个数据集


如果您能更详细地向我们介绍数据的性质和目标,也许有人会想到如何使任务更易于管理。

简短的回答:Python对象开销会让您丧命。在64位机器上的Python2.x中,字符串列表即使在计算字符串的内容之前,每个列表条目也会消耗48字节对于您描述的数组大小来说,这超过了8.7GB的开销。 在32位机器上会更好:每个列表条目只有28字节

更详细的解释:您应该知道Python对象本身可能非常大:即使是像int、float和string这样的简单对象。在您的代码中,您将得到一个字符串列表。在my(64位)上在机器上,即使是空字符串对象也会占用40个字节,为此,您需要在内存中为指向该字符串对象的列表指针添加8个字节。因此,每个条目已经有48个字节,或大约8.7 Gb。鉴于Python一次以8个字节的倍数分配内存,并且您的字符串几乎肯定是非空的,您可以'实际上,每个条目都有56或64个字节(我不知道字符串的长度)

可能的解决办法:

(1) 通过将条目从字符串转换为int或float(视情况而定),您可能会做得更好一些

(2) 使用Python的类型(与list不同!)或使用:则int或float每个只需要4或8个字节

从Python 2.6开始,您可以通过函数获得有关对象大小的基本信息。请注意,如果将其应用于列表(或其他容器),则返回的大小不包括包含的列表对象的大小;仅包括用于保存这些对象的结构的大小。以下是我的计算机上的一些值

>>> import sys
>>> sys.getsizeof("")
40
>>> sys.getsizeof(5.0)
24
>>> sys.getsizeof(5)
24
>>> sys.getsizeof([])
72
>>> sys.getsizeof(range(10))  # 72 + 8 bytes for each pointer
152
替换此项:

_strlf = _strlf[:-1]
为此:

_strlf = [float(val) for val in _strlf[:-1]]
您正在创建一个大的字符串数组。我可以保证字符串
“123.00123214213”
在转换为浮点时占用的内存要少得多

您可能希望包含一些对空值的处理


你也可以选择numpy的数组类型,但你的问题可能太小而不需要麻烦。

为你的计算机购买更多的RAM。如果OP必须处理2GB数据文件、4GB数据文件或6GB数据文件,他所需要的就是继续购买RAM?为什么所有变量名中都有这么多的
\ucode>?你能省去
\ucode>并让它成为ea吗sier to read?因为我需要按行号选择一些数字。例如:我想知道第三行上的所有数字。因此,只需像Ghostdog74所说的那样迭代文件,然后收集第三行上的所有数字。如果需要特定行,可以编写函数扫描文件中的该行并仅读取该行。可能不是fa这是最简单的方法,但可以避免在内存中加载文件。但是当我得到数字时,我还需要知道列的数字。例如:我得到第3行、第2行和第10行。我需要得到每行中第100列的数字。我的程序是一个测试程序。我需要在第一次将数字随机放入L1[]从第二次开始,我需要随机选择三行,如123、421和541。然后从第一行中获取第123列、第421列和第541列的编号。然后从中选择一行,如421。从文件中放入第421行。我建议他应该将数据放入数据库,如SQLite。这样DBMS就可以完成繁琐的工作,他可以有一个好的random访问这张巨大的桌子。呃,你是如何得出数字33175713992544256的?很简单-我在计算器上按了太多次“OK”按钮。;)正确答案当然是182142016,这是一个非常复杂的问题
_strlf = _strlf[:-1]
_strlf = [float(val) for val in _strlf[:-1]]