我在Linux上运行64位Python 3,并且我有一个代码可以生成包含约20,000个元素的列表。当我的代码尝试通过pickle
模块将大约20,000个2D数组的列表写入二进制文件时,发生了内存错误,但是它生成了所有这些数组并将它们附加到此列表中,而没有出现问题。我知道这必须占用大量内存,但是我正在使用的计算机大约有100GB的可用空间(来自命令free -m
)。出现错误的行:
with open('all_data.data', 'wb') as f:
pickle.dump(data, f)
>>> MemoryError
其中data
是我约20,000个numpy数组的列表。另外,以前我试图用大约55,000个元素来运行此代码,但是尽管将所有数组追加到data
列表的过程中占了40%的时间,但是它只是单独输出Killed
。所以现在我试图将其分成多个部分,但是这次我遇到了MemoryError。我该如何绕过呢?我还被告知可以访问多个CPU,但是我不知道如何利用这些CPU(我还不了解multiprocessing
)。
答案 0 :(得分:0)
Pickle将尝试解析所有数据,并可能在将所有内容写入磁盘之前将其转换为中间状态-因此,如果您使用的可用内存大约为一半,它将消耗up尽。
由于您的数据已在列表中,因此一种简单的解决方法是对每个数组进行腌制并存储,而不是尝试一次执行序列化20000个数组的操作:
with open('all_data.data', 'wb') as f:
for item in data:
pickle.dump(item, f)
然后,要读回,只需从文件中解开对象,然后附加到列表中,直到文件用完:
data = []
with open('all_data.data', 'rb') as f:
while True:
try:
data.append(pickle.load(f))
except EOFError:
break
之所以可行,是因为从文件中取消拾取的行为表现得非常好:文件指针恰好停留在文件中存储的腌制对象结束的位置-因此,进一步的读取从下一个对象的开头开始。