为什么 dill.dump 的字典列表(81,000,000 字节)需要永远?

xia*_*hir 0 python dictionary dump large-files dill

我制作了一个 8100000 字节的字典列表,其中包含 900 万多个元素。每个元素都有一个包含 32 对值和键的字典,尽管在每个元素中使用相同的键集。

我想保存它以备将来分析。我已经尝试过 dill.dump,但是我不得不中断内核花了很长时间(超过 1 小时)。这应该是快速而简单的,对吧?

这是我尝试过的:

import dill
output_file=open('result_list', 'wb')
dill.dump(result_list, output_file)
output_file.close()
Run Code Online (Sandbox Code Playgroud)

我也试过泡菜和 bzip2

import bz2
import pickle
output_file=bz2.BZ2File('result_list', 'w')
pickle.dump(result_list, output_file)
Run Code Online (Sandbox Code Playgroud)

但是遇到了内存错误。

有关使此操作可行且耗时更少的任何提示?谢谢!

Mik*_*rns 6

我是dill作者。您可能想尝试klepto这种情况。 dill(实际上任何序列化程序)都会将整个dict对象视为单个对象......而这种大小的东西,您可能希望更像是一个条目数据库......这是klepto可以做的。最快的方法可能是使用存档,将每个条目视为磁盘上单个目录中的不同文件:

>>> import klepto
>>> x = range(10000)
>>> d = dict(zip(x,x))
>>> a = klepto.archives.dir_archive('foo', d)
>>> a.dump()
Run Code Online (Sandbox Code Playgroud)

以上创建了一个包含10000子目录的目录,每个目录中都有一个条目。键和值都被存储。请注意,您也可以稍微调整序列化方法,因此请查看文档以了解如何为您的自定义案例执行此操作。

或者,您可以遍历 dict,并在并行映射中使用 dump 序列化每个条目multiprocess.Pool

(侧面说明,我的作者multiprocessklepto也)。

更新:当问题从序列化一个巨大的字典变为序列化一个巨大的小字典列表时......这改变了答案。

klepto是为大型dict结构而构建的,所以它可能不是你想要的。您可能想尝试dask,它是为大型array结构而构建的。

我认为您还可以遍历列表,单独序列化每个列表条目……只要您以相同的顺序加载它们,您就可以重新构建您的结果。你可以做一些事情,比如用值存储位置,这样你就可以恢复列表,然后在它们乱序时进行排序。

我还请您考虑是否可以将结果重组为更好的形式...