首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加载在附加模式下使用numpy.save保存的数组

加载在附加模式下使用numpy.save保存的数组
EN

Stack Overflow用户
提问于 2016-03-02 12:45:02
回答 1查看 5.2K关注 0票数 4

我在附加模式下使用numpy.save()保存数组:

代码语言:javascript
复制
f = open("try.npy", 'ab')
sp.save(f,[1, 2, 3, 4, 5])
sp.save(f,[6, 7, 8, 9, 10])
f.close()

然后,我可以以LIFO模式加载数据吗?也就是说,如果我现在要加载6-10数组,是否需要加载两次(使用b):

代码语言:javascript
复制
f = open("try.npy", 'r')
a = sp.load(f)
b = sp.load(f)
f.close()

或者我可以直接加载第二个附加的保存?

EN

回答 1

Stack Overflow用户

发布于 2016-03-02 16:21:40

我对这种顺序的保存和加载工作感到有点惊讶。我不认为这是有记录的(请纠正我)。但是很明显,每个save都是一个独立的单元,load读取到该单元的末尾,而不是文件的末尾。

将每个load看作是一个readline。您不能只读取文件的最后一行;您必须读取文件之前的所有行。

有一种读取最后一个文件的方法--使用seek将读取的文件移动到一个特定的点。但是,要做到这一点,您必须准确地知道所需的块从何处开始。

np.savez是将多个数组保存到一个文件,或者更确切地说是一个压缩存档的方法。

save保存两个部分,一个包含dtypeshapestrides等信息的标头和一个数组数据缓冲区的副本。nbytes属性提供数据缓冲区的大小。至少对于数字和字符串dtype是这样的。

save文档中有一个使用打开的文件的示例--使用seek(0)将文件倒带以供load使用。

np.lib.npyio.format有关于保存格式的更多信息。看起来可以通过读取头的前几个字节来确定头的长度。您可能可以使用模块中的函数来执行所有这些读取和计算。

如果我从示例中读取整个文件,就会得到:

代码语言:javascript
复制
In [696]: f.read()
Out[696]: 
b"\x93NUMPY\x01\x00F\x00
{'descr': '<i4', 'fortran_order': False, 'shape': (5,), }\n
 \x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00
\x93NUMPY\x01\x00F\x00
{'descr': '<i4', 'fortran_order': False, 'shape': (5,), }\n
 \x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t\x00\x00\x00\n\x00\x00\x00"

我添加了换行以突出显示该文件的不同部分。注意,每个save都以\x93NUMPY开头。

使用打开的文件f,我可以使用以下方法读取头(或第一个数组):

代码语言:javascript
复制
In [707]: np.lib.npyio.format.read_magic(f)
Out[707]: (1, 0)
In [708]: np.lib.npyio.format.read_array_header_1_0(f)
Out[708]: ((5,), False, dtype('int32'))

我可以用以下内容载入这些数据:

代码语言:javascript
复制
In [722]: np.fromfile(f, dtype=np.int32, count=5)
Out[722]: array([1, 2, 3, 4, 5])

我从np.lib.npyio.format.read_array函数代码中推断出这一点。

现在,该文件定位于:

代码语言:javascript
复制
In [724]: f.tell()
Out[724]: 100

它是下一个数组的头:

代码语言:javascript
复制
In [725]: np.lib.npyio.format.read_magic(f)
Out[725]: (1, 0)
In [726]: np.lib.npyio.format.read_array_header_1_0(f)
Out[726]: ((5,), False, dtype('int32'))
In [727]: np.fromfile(f, dtype=np.int32, count=5)
Out[727]: array([ 6,  7,  8,  9, 10])

我们在EOF。

知道int32有4个字节,我们就可以计算出数据占20个字节。因此,我们可以跳过一个数组,方法是读取头部,计算数据块的大小,然后seek通过它到达下一个数组。对于小数组来说,这样做是不值得的;但是对于非常大的数组,它可能是有用的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35747614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档