使用Python频繁更新数值实验中存储的数据

2024-05-19 02:50:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在进行一个需要多次迭代的数值实验。每次迭代之后,我希望将数据存储在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()

问题:

  1. 谢尔夫是不是更好的选择?或者其他一些我不知道的python库?在
  2. 我使用datadict是因为当我做更多的实验时,如果我需要改变一些事情,它更容易编码,也更灵活。使用预先分配的阵列会有很大的优势吗?在
  3. 打开和关闭文件会影响运行时吗?我这样做是为了除了我设置的文本日志之外,我还可以检查进度。在

谢谢你的帮助!在


Tags: 文件of数据in程序数据结构fordata
2条回答
  1. 假设你在数值实验中使用numpy,而不是{a1},我建议使用numpy.savez。在
  2. 保持简单,只有当您觉得脚本运行太长时才进行优化。在
  3. 打开和关闭文件确实会影响运行时,但是有一个备份无论如何都会更好。在

我会用collections.defaultdict(list)代替普通的dict和{}。在

不过,搁架可能不是个好选择。。。在

您可以尝试使用kleptojoblib。两者都擅长缓存结果,并且可以使用高效的存储格式。在

joblib和{}都可以将结果保存到磁盘上的文件或目录中。两者都可以利用numpy内部存储格式和/或保存时的压缩…还可以根据需要保存到内存映射文件。在

如果使用klepto,它将字典键作为文件名,并将值保存为内容。使用klepto,您还可以选择使用pickle还是{}或其他一些存储格式。在

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的目录,其中包含pickled文件,data_dict的每个键对应一个。有一些关键字用于使用memmap文件,也有用于压缩级别的关键字。如果您选择cached=False,那么每次写入data_dict时,您将不再转储到文件,而是每次写入内存……然后您可以使用data_dict.dump()在您选择时转储到磁盘……或者您可以选择一个内存限制,当您命中它时,您将转储到磁盘。此外,您还可以选择一种缓存策略(如lru或{}),以决定将哪些键从内存中清除并转储到磁盘。在

获取klepto此处:https://github.com/uqfoundation

或者在这里得到joblibhttps://github.com/joblib/joblib

如果您重构,您可能会想出一种方法来实现这一点,这样它就可以利用预先分配的数组。但是,这可能取决于代码如何运行的概要文件。在

打开和关闭文件会影响运行时吗?对。如果使用klepto,则可以设置要转储到磁盘的粒度。然后,您可以在速度和结果的中间存储之间进行权衡。在

相关问题 更多 >

    热门问题