【问题标题】:How to save big (not huge) dictonaries in Python?如何在 Python 中保存大(不是大)字典?
【发布时间】:2012-03-03 05:27:02
【问题描述】:

我的字典将包含数千个键,每个键都有一个 1000x1000 numpy 数组作为值。我不需要该文件是人类可读的。小尺寸和快速加载时间更重要。

首先我尝试了savemat,但我遇到了problemsPickle 产生了一个巨大的文件。我假设 csv 也是如此。我读过推荐使用json(可读文本可能很大)或db(假设很复杂)的帖子。对于我的情况,你会推荐什么?

【问题讨论】:

  • “在一个巨大的文件中”?定义巨大。 1000x1000 是一百万个值。每个值都是一个 int,那么你就有 4Mb 的数据。
  • @S.Lott 它产生了一个 1.6 GB 的文件
  • 按照 S.Lott 的计算,只有 410 个 Keys 和一个 1000x1000 int 矩阵。
  • @Framester:你为什么希望它更小?
  • @S.Lott:我希望所有矩阵都以压缩字节码保存的文件比以纯文本保存的情况要小得多。

标签: python file-io dictionary numpy scipy


【解决方案1】:

您可以使用 PyTables (http://www.pytables.org/moin) ,并将您的数据保存为 HDF5 格式。

【讨论】:

    【解决方案2】:

    Google 的Protobuf 规范旨在在开销方面非常有效。我不确定(反)序列化它的速度有多快,但作为谷歌,我想它并不简陋。

    【讨论】:

      【解决方案3】:

      numpy.savez 怎么样?它可以保存多个numpy数组,它们是二进制的,所以它应该比pickle更快。

      【讨论】:

      • 腌制数据也是二进制的,只要您使用协议 0(即 ASCII)以外的东西。为了速度,请使用cPickle
      • @GregHewgill 我知道 cPickle 但不知道你可以有二进制泡菜。谢谢! // 并不意味着破坏良好的后续,但我认为在这种情况下使用 savez 更快,因为它专门用于保存 numpy 数组。好吧,我想这也取决于大小,所以当然需要基准来决定。
      • 是的,savez 适合这种情况。只是想让您了解不同的泡菜协议。
      • 谢谢,但我在使用文件名作为键时遇到了麻烦:stackoverflow.com/q/9258069/380038
      【解决方案4】:

      如果你有一个字典,其中键是字符串,值是数组,像这样:

      >>> import numpy
      >>> arrs = {'a': numpy.array([1,2]),
                  'b': numpy.array([3,4]),
                  'c': numpy.array([5,6])}
      

      您可以使用numpy.savez 将它们按键保存到压缩文件中:

      >>> numpy.savez('file.npz', **arrs)
      

      要加载它:

      >>> npzfile = numpy.load('file.npz')
      >>> npzfile
      <numpy.lib.npyio.NpzFile object at 0x1fa7610>
      >>> npzfile['a']
      array([1, 2])
      >>> npzfile['b']
      array([3, 4])
      >>> npzfile['c']
      array([5, 6])
      

      【讨论】:

      • 谢谢,但我在使用文件名作为键时遇到了麻烦:stackoverflow.com/q/9258069/380038
      • 你可以只转义键名。
      • 另外,这个 NpzFile 对象可以被类型转换为字典,以防你想要一个简单的字典输入,字典输出。
      【解决方案5】:

      文件系统本身通常是一种未被充分认识的数据结构。您可以有一个字典,它是从键到文件名的映射,然后每个文件中都有 1000x1000 数组。 Pickling 字典会快速简单,然后数据文件可以只包含原始数据(numpy 可以轻松加载)。

      【讨论】:

      • 感谢您的快速答复。我实际上将所有密钥作为单个文件 atm,但我想更改它,因为加载所有这些文件需要大约 15 分钟。
      • @Framester:什么告诉你它慢是因为文件的数量而不是文件的大小?
      • @Framester:使用内存映射文件 (mmap module) 进行调查。然后几乎没有“加载”数据的成本,它都是按需访问的。不过,您可能需要 64 位操作系统来映射所有数据。
      • @Nobody:访问大量小文件不是比访问一个内容相同的大文件慢还是慢。
      • @Framester:是的,它比较慢,但你必须考虑到多少。如果您需要 15 分钟来读取整个数据而只需 1 秒来浏览文件,那么考虑移动到一个文件是不值得的。如果是相反的方式,那么当然应该这样做^^
      猜你喜欢
      • 2017-04-08
      • 1970-01-01
      • 2014-03-30
      • 2021-02-28
      • 2011-07-12
      • 2014-06-25
      • 1970-01-01
      • 2013-08-05
      • 2017-05-04
      相关资源
      最近更新 更多