【问题标题】:How to use numpy.save in append mode如何在附加模式下使用 numpy.save
【发布时间】:2018-09-06 09:39:00
【问题描述】:

我在我的项目中使用numpy.savenumpy.load 来读写大型 数据集。我意识到numpy.save 不应用附加模式。例如(Python 3):

import numpy as np

n = 5
dim = 5
for _ in range(3):
    Matrix = np.random.choice(np.arange(10, 40, dim), size=(n, dim))
    np.save('myfile', Matrix)

M1 = np.load('myfile.npy', mmap_mode='r')[1:7].copy()
print(M1)

使用切片[1:7] 加载数据的特定部分是不正确的,因为np.save 没有附加。我找到了这个answer,但它看起来很奇怪(file(filename, 'a') 什么是文件file??)。是否有一种巧妙的解决方法可以在不使用额外列表的情况下实现这一目标?

【问题讨论】:

  • afile 表示使用追加模式打开文件
  • file 是什么?” 这是一个Python 2 builtin function。它在 Python 3 中被删除。
  • @Zhiya 是的,但是它会这样抱怨write() argument must be str, not bytes 这是因为Matrix
  • @Medo 我们可以看到你的代码和错误吗?
  • np.load('myfile.npy', mmap_mode='r')[1:7] 无论如何也行不通。 npy 文件格式不能这样工作。

标签: python python-3.x python-2.7 numpy


【解决方案1】:

npy 文件格式不能这样工作。 npy 文件对 single 数组进行编码,其标头指定形状、dtype 和其他元数据。您可以在 NumPy 文档中查看 npy file format spec

支持附加数据不是npy 格式的设计目标。即使您设法让numpy.save 附加到现有文件而不是覆盖内容,结果也不会是有效的npy 文件。生成带有附加数据的有效npy 文件需要重写标头,并且由于这可能需要调整标头大小,它可能会移动数据并需要重写整个文件。

NumPy 没有将数据附加到现有npy 文件的工具,除了将数据读入内存、构建新数组以及将新数组写入文件之外。如果您想保存更多数据,请考虑编写一个新文件,或选择其他文件格式。

【讨论】:

  • 有道理!非常感谢
【解决方案2】:

在 Python3 中重复 saveload 到同一个打开的文件工作:

In [113]: f = open('test.npy', 'wb')
In [114]: np.save(f, np.arange(10))
In [115]: np.save(f, np.zeros(10))
In [116]: np.save(f, np.ones(10))
In [117]: f.close()
In [118]: f = open('test.npy', 'rb')
In [119]: for _ in range(3):
     ...:     print(np.load(f))
     ...:     
[0 1 2 3 4 5 6 7 8 9]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
In [120]: np.load(f)
OSError: Failed to interpret file <_io.BufferedReader name='test.npy'> as a pickle

每个save 将一个自包含的数据块写入文件。它由一个标题块和一个数据缓冲区的图像组成。标头块包含有关数据缓冲区长度的信息。

每次加载都会读取定义的头块,以及已知的数据字节数。

据我所知,这没有记录在案,但已在之前的 SO 问题中得到证明。从saveload 代码中也可以看出这一点。

请注意,这些是单独的数组,在保存和加载时都是如此。但如果尺寸兼容,我们可以将负载连接到一个文件中。

In [122]: f = open('test.npy', 'rb')
In [123]: np.stack([np.load(f) for _ in range(3)])
Out[123]: 
array([[0., 1., 2., 3., 4., 5., 6., 7., 8., 9.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
In [124]: f.close()

Append multiple numpy files to one big numpy file in python

loading arrays saved using numpy.save in append mode

【讨论】:

  • 值得注意的是,这与提问者正在使用的mmap_mode 不兼容。除此之外,我想说的是,当内容实际上是基于 NPY 的 ad-hoc 格式时,调用这样的文件 anything.npy 会产生误导,我建议使用不同形式的数据存储。例如,npz 格式,它只是一个包含npy 文件的 zip 文件,您可以使用zipfile 标准库模块对其进行操作和添加数据。
【解决方案3】:

file 函数在 Python 3 中已弃用。虽然我不保证它可以工作,但与您问题中链接中的代码等效的 Python 3 代码将是

with open('myfile.npy', 'ab') as f_handle:
    np.save(f_handle, Matrix)

这应该将Matrix 附加到'myfile.npy'

【讨论】:

  • 非常感谢。我尝试了你的建议,但因为 Matrix 是 numpy 列表,我收到此错误 TypeError: write() argument must be str, not bytes
猜你喜欢
  • 2016-06-15
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多