当dtype=obj时,迭代地读取一个大的numpy保存文件(即使用生成器)

2024-04-25 23:37:21 发布

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

我有一个很大的numpy保存文件(可能比内存大小还要大)。dtypeobject(它是一个可变长度numpy数组的numpy数组)。在

Can I avoid reading the entire file into memory?
E.g. build a generator to read elements iteratively.

使用标准numpy dtypesnp.load(filename, mmap_mode='r')可以做到这一点,但不能将mmap_mode用于对象数据类型。在

有没有可能我可以通过读卡器流式传输字节?还是我不知道的另一个把戏?在


Tags: 文件thenumpyobjectmode数组canfile
2条回答

你可能想看看numpy memmap。在

根据官方文件:

Memory-mapped files are used for accessing small segments of large files on disk, without reading the entire file into memory. NumPy’s memmap’s are array-like objects. This differs from Python’s mmap module, which uses file-like objects.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

非对象数据类型的基本格式是一个头块(包括shape、dtype、stripes等),后面是其数据缓冲区的字节副本。在

换句话说,类似于这个序列的东西:

In [129]: x
Out[129]: 
array([[1, 2, 3],
       [4, 5, 6]])
In [130]: x.tostring()
Out[130]: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00'
In [132]: np.frombuffer(__, dtype=int)
Out[132]: array([1, 2, 3, 4, 5, 6])

但如果我将dtype更改为object:

^{pr2}$

这些数据缓冲区字节指向内存中的位置。因为这些都是小整数,所以它们可能指向唯一的缓存值

In [137]: id(1)
Out[137]: 139402080
In [138]: id(2)
Out[138]: 139402096

如果元素是数组,它们将指向存储在内存中其他地方的数组(指向ndarray对象,而不是它们的数据缓冲区)。在

要处理这样的对象,np.save使用pickle。现在,ndarray的pickle是它的save字符串。我不知道np.save将这些字符串放在哪里。可能在后面的文件中使用指向流的指针。在

您/我们必须研究np.save(和函数调用)来确定如何保存这些数据。我已经了解了如何从一个文件中保存和加载多个数组,但没有关注对象dtype布局。相关代码在numpy/lib/npyio.pynumpy/lib/format.py

format文件有一个关于保存格式的doc块。在

np.save
   format.write_array

如果非对象write_array使用array.tofile(fp)。如果object,则使用pickle.dump(array, fp)

类似地,read_array使用np.fromfile(fp, dtype)和{}。在

所以这意味着我们需要深入研究arraypickle.dump是如何完成的。在

相关问题 更多 >