【问题标题】:Saving multiple Numpy arrays to a Numpy binary file (Python)将多个 Numpy 数组保存到 Numpy 二进制文件(Python)
【发布时间】:2020-07-21 23:02:30
【问题描述】:

我想将多个大型 numpy 数组保存到一个 numpy 二进制文件中,以防止我的代码崩溃,但是当我添加数组时,它似乎一直被覆盖。最后保存的数组是打开和读取 save.npy 时设置为 allarrays 的内容。这是我的代码:

with open('save.npy', 'wb') as f:
     for num in range(500):
          array = np.random.rand(100,400)
          np.save(f, array)

with open('save.npy', 'rb') as f:
     allarrays = np.load(f)

如果该文件以前存在,我希望在重新运行代码时覆盖它。这就是我选择“wb”而不是“ab”的原因。

【问题讨论】:

  • 您的代码所做的只是覆盖之前保存的数组。您可以创建一个包含所有数据的数组,也可以使用h5py 创建一个数据集
  • 我无法创建一个包含我所有数据的数组,因为当它变得太高时它开始崩溃,特别是对于大小相对较大的图像文件(每个文件 40mb,其中 500 多个) .我用于“转换”我的数组而不是随机生成数组(如此处所示)的库是一个 C 扩展库,当文件大小过大时,某些文件似乎会崩溃。 h5py 会对此有所帮助吗?
  • 我的想法是将转换后的数组保存到 numpy 二进制文件,因为每次我转换数组以节省内存空间并将其临时放入磁盘空间。
  • 是的,您可以为每个单独的文件名创建一个数据集并相应地读/写
  • h5py 数据集也将比 numpy 文件快得多

标签: python python-3.x numpy binaryfiles


【解决方案1】:
 alist =[]
 with open('save.npy', 'rb') as f: 
      alist.append(np.load(f))

加载时,您已将所有加载收集到列表或其他内容中。 load 只加载一个数组,从当前文件位置开始。

【讨论】:

  • 然后我会将alist 转换为 numpy 数组?我需要返回的最终数组以 500x500x500 为例
【解决方案2】:

您可以尝试将内存映射到磁盘。

# merge arrays using memory mapped file
mm = np.memmap("mmap.bin", dtype='float32', mode='w+', shape=(500,100,400))
for num in range(500):
    mm[num::] = np.random.rand(100,400)

# save final array to npy file
with open('save.npy', 'wb') as f:
    np.save(f, mm[::])

【讨论】:

  • 内存映射和保存为 numpy 文件的性能如何?我注意到内存映射限制为 2.5gb。如果文件比那个大怎么办?我是否只做与所示相同的操作,但要多次保存/加载?
  • 2.5 gb 限制适用于 32 位系统,这将是任何文件(mmap 或 npy)的限制。在这种情况下,您可以为每个数组使用相同的 memmap 文件,然后将每个数组保存到不同的 npy 文件中。
【解决方案3】:

我也遇到了这个问题,并以一种不是很简洁的方式解决了它,但也许它对其他人有用。它受到 hpaulj 方法的启发,该方法不完整(即不加载数据)。也许这不是一个人一开始就应该解决这个问题的方式......但无论如何,请继续阅读。

我使用与 OP 类似的程序保存了我的数据,

# Saving the data in a for-loop
with open(savefilename, 'wb') as f:
    for datafilename in list_of_datafiles:
        # Do the processing
        data_to_save = ...
        np.save( savefilename, data_to_save )

遇到了调用np.load() 只加载最后保存的数组,其余的都不加载的问题。但是,我知道数据原则上包含在*.npy 文件中,因为文件大小在保存循环期间不断增长。所需要的是简单地循环遍历 numpy 数组的内容,同时重复调用 load 命令。由于我不太清楚文件中包含多少文件,所以我只是循环加载循环直到它失败。这很 hacky,但它可以工作。

# Loading the data in a for-loop
data_to_read = []
with open(savefilename, 'r') as f:
    while True:
        try:
            data_to_read.append( np.load(f) )
        except:
            print("all data has been read!")
            break

然后您可以调用例如len(data_to_read) 来查看其中包含多少个数组。调用,例如,data_to_read[0] 会为您提供第一个保存的数组等。

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2018-12-15
    • 2021-04-29
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多