Python 当dtype=object时,以迭代方式(即使用生成器)读取大型numpy保存文件
我有一个很大的numpy保存文件(可能比内存中的文件大)。Python 当dtype=object时,以迭代方式(即使用生成器)读取大型numpy保存文件,python,numpy,memory-mapped-files,Python,Numpy,Memory Mapped Files,我有一个很大的numpy保存文件(可能比内存中的文件大)。dtype是object(它是一个可变长度numpy数组的numpy数组) 我可以避免将整个文件读入内存吗 例如,构建一个生成器以迭代方式读取元素 使用标准的numpydtypesnp.load(filename,mmap_mode='r')就可以了,但不能对对象数据类型使用mmap_mode 有没有可能通过读卡器传输字节?还是我不知道的另一个技巧?您可能想看看numpy memmap 从官方文件: 内存映射文件用于访问磁盘上大文件的小段
dtype
是object
(它是一个可变长度numpy数组的numpy数组)
我可以避免将整个文件读入内存吗例如,构建一个生成器以迭代方式读取元素 使用标准的numpy
dtypes
np.load(filename,mmap_mode='r')
就可以了,但不能对对象数据类型使用mmap_mode
有没有可能通过读卡器传输字节?还是我不知道的另一个技巧?您可能想看看numpy memmap 从官方文件: 内存映射文件用于访问磁盘上大文件的小段,而无需将整个文件读入内存。NumPy的memmap是类似数组的对象。这与Python的mmap模块不同,后者使用类似文件的对象
非对象数据类型的基本格式是头块(带有形状、数据类型、步幅等),后跟数据缓冲区的字节副本 换句话说,类似于这个序列的东西:
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])
但如果我将数据类型更改为object:
In [134]: X = x.astype(object)
In [135]: X
Out[135]:
array([[1, 2, 3],
[4, 5, 6]], dtype=object)
In [136]: X.tostring()
Out[136]: b'`\x1bO\x08p\x1bO\x08\x80\x1bO\x08\x90\x1bO\x08\xa0\x1bO\x08\xb0\x1bO\x08'
这些数据缓冲区字节指向内存中的位置。由于这些是小整数,它们可能指向唯一的缓存值
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
(和函数调用)以确定如何保存此数据。我已经研究了如何从文件中保存和加载多个数组,但没有关注对象数据类型布局。相关代码位于numpy/lib/npyio.py
,numpy/lib/format.py
格式
文件有一个关于保存格式的文档块
np.save
format.write_array
如果非对象write\u数组
使用array.tofile(fp)
。如果对象
,则使用pickle.dump(数组,fp)
类似地,read\u array
使用np.fromfile(fp,dtype)
和pickle.load
因此,这意味着我们需要深入研究
数组pickle.dump
是如何完成的。Anumpy
数组dtype=object
并不是numpy
围绕处理而设计的。你可能会考虑一种完全不同的方法来序列化你的数据。不幸的是,我没有对序列化过程的控制。好吧,那么我认为你除了遵循HPAULJ的回答中的建议外,别无选择,并找出一种使用RAW流反序列化这个方法的方法。MMEAP以二进制方式读取文件。返回平坦的字节数组。然后,问题是以迭代的方式将这些字节转换为原始形式,而numpy的memmap函数并没有涵盖这一点。