我需要随机获取一行的数字,并将每行放在其他数组中,然后获取一行的数字。
我有一个超过400M的大文件。在该文件中,有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()
这是我的错误信息:
MemoryError:
File "D:\research\space-function\ART3.py", line 30, in <module>
_strlf = _strlf.split('\t')
答案 0 :(得分:7)
你可能想以另一种方式处理你的问题。逐行处理文件。我认为不需要将整个大文件存储到数组中。否则,您可能想告诉我们您实际上想要做什么。
for line in open("400MB_file"):
# do something with line.
或
f=open("file")
for linenum,line in enumerate(f):
if linenum+1 in [2,3,10]:
print "there are ", len(line.split())," columns" #assuming you want to split on spaces
print "100th column value is: ", line.split()[99]
if linenum+1>10:
break # break if you want to stop after the 10th line
f.close()
答案 1 :(得分:3)
这是一个简单的例子,你的程序要求的内存比计算机可用的内存多。 13496x13496元素的数组需要182,142,016个“单元”,其中一个单元最少为一个字节(如果存储字符),可能还有几个字节(例如,如果存储浮点数)。我甚至没有考虑你的特定运行时'数组元数据,虽然这通常是一个简单数组上的微小开销。
假设每个数组元素只是一个字节,那么您的计算机需要大约180MB的RAM才能将其整个存储在内存中。试图处理它可能是不切实际的。
你需要以不同的方式思考问题;正如已经提到的,逐行方法可能是更好的选择。或者可能以较小的单位处理网格,可能是10x10或100x100,并汇总结果。或者也许问题本身可以用不同的形式表达,这避免了完全处理整个数据集的需要......?
如果您向我们提供有关数据性质和目标的更多详细信息,也许有人会有想法让任务更易于管理。
答案 2 :(得分:3)
简短回答:Python对象开销正在扼杀你。在64位机器上的Python 2.x中,即使在考虑字符串的内容之前,每个列表条目的字符串列表也会消耗48个字节。对于您描述的阵列大小,这超过了8.7 Gb的开销。 在32位机器上它会好一点:每个列表条目只有28个字节。
更长的解释:你应该知道Python对象本身可能非常大:甚至是简单的对象,如整数,浮点数和字符串。在您的代码中,您最终会得到一个字符串列表列表。在我的(64位)机器上,即使是一个空字符串对象占用40个字节,为此,您需要为指向内存中此字符串对象的列表指针添加8个字节。所以每个条目已经有48个字节,大约是8.7 Gb。鉴于Python一次以8个字节的倍数分配内存,并且你的字符串几乎肯定是非空的,你实际上每个条目看56或64个字节(我不知道你的字符串有多长)。
可能的解决方案:
(1)您可以根据需要将条目从字符串转换为整数或浮点数,从而做得更好。
(2)你可以通过使用Python的array类型(与列表不同!)或使用numpy来更好地 :那么你的整数或者浮点数每个只需4或8个字节。
从Python 2.6开始,您可以使用sys.getsizeof
函数获取有关对象大小的基本信息。请注意,如果将其应用于列表(或其他容器),则返回的大小不包括所包含的列表对象的大小;仅用于保存这些对象的结构。这是我机器上的一些值。
>>> 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
答案 3 :(得分:0)
MemoryError例外:
当某个操作耗尽时,提升 记忆,但情况可能仍然存在 获救(通过删除一些对象)。 关联的值是一个字符串 表明什么样的(内部) 操作耗尽内存。注意 因为底层的记忆 管理架构(C的malloc() 功能),翻译可能不会 总是能够完全恢复 从这种情况;不过呢 引发异常以便堆栈 如果是,可以打印回溯 逃跑计划是原因。
似乎至少在你的情况下,将整个文件读入内存并不是一个可行的选择。
答案 4 :(得分:0)
替换它:
_strlf = _strlf[:-1]
用这个:
_strlf = [float(val) for val in _strlf[:-1]]
你正在制作一大堆字符串。我可以保证字符串"123.00123214213"
在将其转换为浮点时占用的内存要少得多。
您可能希望包含一些空值处理。
您也可以使用numpy的数组类型,但您的问题可能太小而无法理解。