我正在处理一堆大型numpy数组,由于这些数组最近开始占用太多内存,我想用numpy.memmap
实例替换它们。问题是,有时我必须调整数组的大小,我最好是就地调整。这在普通数组上运行得很好,但是在memmaps上尝试这样做会抱怨数据可能被共享,甚至禁用refcheck也没有帮助。在
a = np.arange(10)
a.resize(20)
a
>>> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
a = np.memmap('bla.bin', dtype=int)
a
>>> memmap([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
a.resize(20, refcheck=False)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-41-f1546111a7a1> in <module>()
----> 1 a.resize(20, refcheck=False)
ValueError: cannot resize this array: it does not own its data
调整底层mmap缓冲区的大小非常好。问题是如何将这些更改反映到数组对象中。我见过这个workaround,但不幸的是它没有适当地调整数组的大小。{1.0版本显然还没有调整大小。还有其他想法,如何覆盖内置的调整大小检查?在
问题是创建数组时,OWNDATA标志为False。您可以通过在创建数组时要求标志为True来更改:
唯一需要注意的是,它可能会创建数组并复制一个副本,以确保满足要求。在
编辑到地址保存:
如果要将重新调整大小的数组保存到磁盘,可以将memmap保存为.npy格式的文件,并在需要重新打开它并用作memmap时以
^{pr2}$numpy.memmap
的形式打开:编辑以提供另一种方法:
通过重新调整基本mmap的大小(a.base或.u mmap,以uint8格式存储)并“重新加载”memmap,您可以接近您所要查找的内容:
如果我没弄错的话,这基本上实现了@wwwslinger的第二个解决方案所做的,但不必手动指定新memmap的大小(以位为单位):
当新数组需要比旧数组大时,这种方法很有效,但我不认为这种方法会允许内存映射文件的大小在新数组较小时自动截断。在
像@wwwslinger的回答一样,手动调整基的大小似乎允许文件被截断,但这不会减少数组的大小。在
例如:
^{pr2}$相关问题 更多 >
编程相关推荐