在不知道形状的情况下加载np.memmap

时间:2016-04-20 15:51:15

标签: python numpy memory-mapped-files joblib

是否可以在不知道形状的情况下加载numpy.memmap并仍然可以恢复数据的形状?

data = np.arange(12, dtype='float32')
data.resize((3,4))
fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4))
fp[:] = data[:]
del fp
newfp = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))

在最后一行中,我希望不能指定形状,仍然可以使变量newfp具有(3,4)形状,就像joblib.load一样。这可能吗?感谢。

3 个答案:

答案 0 :(得分:8)

除非该信息已明确存储在某个文件中。就np.memmap而言,该文件只是一个扁平缓冲区。

我建议使用np.save来保存numpy数组,因为这样也会保留指定其维度,dtypes等的元数据。您还可以通过传递{{1}将.npy文件作为memmap加载参数np.load

joblib.dump使用pickle组合存储通用Python对象和memmap_mode=来存储numpy数组。

要初始化由np.save文件支持的空内存映射阵列,您可以使用.npy

numpy.lib.format.open_memmap

即使阵列大于总可用磁盘空间,这也可能会让您感到惊讶(我的笔记本电脑只有500GB SSD,但我刚刚创建了一个10TB的memmap)。这是可能的,因为创建的文件是sparse

发现import numpy as np from numpy.lib.format import open_memmap # initialize an empty 10TB memory-mapped array x = open_memmap('/tmp/bigarray.npy', mode='w+', dtype=np.ubyte, shape=(10**13,)) 的信用应该转到kiyo's previous answer here

答案 1 :(得分:1)

来自@ali_m的answer完全有效。我想提一下我的个人偏好,万一它可以帮助任何人。我总是以形状作为前2个元素开始我的memmap数组。这样做很简单:

# Writing the memmap array
fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4))
fp[:] = data[:]
fp = np.memmap(filename, dtype='float32', mode='r+', shape=(14,))
fp[2:] = fp[:-2]
fp[:2] = [3, 4]
del fp

或者更简单:

# Writing the memmap array
fp = np.memmap(filename, dtype='float32', mode='w+', shape=(14,))
fp[2:] = data[:]
fp[:2] = [3, 4]
del fp

然后您可以轻松地将数组读取为:

#reading the memmap array
newfp = np.memmap(filename, dtype='float32', mode='r')
row_size, col_size = newfp[0:2]
newfp = newfp[2:].reshape((row_size, col_size))

答案 2 :(得分:0)

numpy.memmap的替代方法是tifffile.memmap

from tifffile import memmap
newArray = memmap("name", shape=(3,3), dtype='uint8')
newArray[1,1] = 11
del(newArray)

newArray文件的创建具有以下值:

0  0  0
0  11 0
0  0  0  

现在让我们读回它:

array = memmap("name", dtype='uint8')
print(array.shape) # prints (3,3)
print(array)

打印:

0  0  0
0  11 0
0  0  0