我正在进行一项需要多次迭代的数值实验。在每次迭代之后,我想将数据存储在pickle文件或类似pickle的文件中,以防程序超时或数据结构被点击。什么是最好的方法。这是骨架代码:
data_dict = {} # maybe a dictionary is not the best choice
for j in parameters: # j = (alpha, beta, gamma) and cycle through
for k in number_of_experiments: # lots of experiments (10^4)
file = open('storage.pkl', 'ab')
data = experiment() # experiment returns some numerical value
# experiment takes ~ 1 seconds, but increase
# as parameters scale
data_dict.setdefault(j, []).append(data)
pickle.dump(data_dict, file)
file.close()
问题:
感谢您的帮助!
答案 0 :(得分:1)
numpy
进行数值实验,而不是pickle我建议使用numpy.savez。我会使用collections.defaultdict(list)
代替普通dict
和setdefault
。
答案 1 :(得分:1)
Shelve可能不是一个好选择,但是......
您可以尝试使用klepto
或joblib
。两者都擅长缓存结果,并且可以使用高效的存储格式。
joblib
和klepto
都可以将结果保存到磁盘上的文件或目录中。如果您愿意,两者还可以利用numpy
内部存储格式和/或压缩保存...并保存到内存映射文件。
如果使用klepto
,则将字典键作为文件名,并将值保存为内容。使用klepto
,您还可以选择是否要使用pickle
或json
或其他一些存储格式。
Python 2.7.7 (default, Jun 2 2014, 01:33:50)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import klepto
>>> data_dict = klepto.archives.dir_archive('storage', cached=False, serialized=True)
>>> import string
>>> import random
>>> for j in string.ascii_letters:
... for k in range(1000):
... data_dict.setdefault(j, []).append([int(10*random.random()) for i in range(3)])
...
>>>
这将创建一个名为storage
的目录,其中包含pickle文件,每个密钥对应data_dict
。有关于使用memmap
文件的关键字,也有压缩级别的关键字。如果选择cached=False
,那么每次写入data_dict
时都不会转储到文件中,而是每次都写入内存...然后您可以使用data_dict.dump()
转储到磁盘你选择...或者你可以选择一个内存限制,当你点击它时,你将转储到磁盘。此外,您还可以选择缓存策略(如lru
或lfu
)来决定从内存中清除哪些密钥并转储到磁盘。
在此处获取klepto
:https://github.com/uqfoundation
或在此处获取joblib
:https://github.com/joblib/joblib
如果你重构,你可能想出办法来做到这一点,这样它就可以利用预先分配的数组。但是,它可能取决于代码运行方式的配置文件。
打开和关闭文件会影响运行时间吗?是。如果使用klepto
,则可以设置要转储到磁盘的粒度。然后,您可以选择速度与结果的中间存储之间的权衡。