2016-04-21 32 views
1

是否有方法將numpy memmap數組保存到.npy文件中?顯然,有從.npy文件加載這樣的陣列如下將numpy memmap刷新到npy文件

data = numpy.load("input.npy", mmap_mode='r') 

但沖洗該文件不等同於將其存儲在.npy格式的方法。

如果沖洗是唯一的出路,那麼有沒有辦法來推斷存儲陣列的形狀?我更喜歡在另一個腳本中自動存儲和檢索動態形狀(可能再次作爲memmap)。

我已經在各種地方搜索了這個,但沒有找到任何結果。我的方式來存儲到.npy我現在要做的是

numpy.save(output.filename, output.copy()) 

這違背了使用MEMMAP的想法,但保留了形狀。

注:我知道hdf5和h5py,但我想知道是否有一個純粹的numpy解決方案。

回答

3

有沒有一種方法來推斷存儲數組的形狀?

No。就np.memmap而言,文件只是一個緩衝區 - 它存儲數組的內容,但不包括維度,dtype等等。除非它以某種方式包含在數組本身內,否則無法推斷該信息。如果您已經創建了一個支持簡單二進制文件的np.memmap,那麼您需要將其內容寫入磁盤上的新文件.npy

你可以通過避免使用numpy.lib.format.open_memmap打開新.npy文件作爲另一個內存映射陣列生成內存中的副本:

import numpy as np 
from numpy.lib.format import open_memmap 

# a 10GB memory-mapped array 
x = np.memmap('/tmp/x.mm', mode='w+', dtype=np.ubyte, shape=(int(1E10),)) 

# create a memory-mapped .npy file with the same dimensions and dtype 
y = open_memmap('/tmp/y.npy', mode='w+', dtype=x.dtype, shape=x.shape) 

# copy the array contents 
y[:] = x[:] 
+1

這'open_memmap'功能是一個偉大的發現 - 我只需要以'.npy'支持數組的方式,但增加一個選項保存可能卡在二進制文件中的數組甚至更好。 – pevogam

1

免責聲明:與numpy的版本1.11.2下工作(後來我想, ),但我嘗試過的早期版本(1.8.2)給出了一個錯誤。

np.save保存的數組本質上是一個帶有指定dtype,shape和元素順序的頭的memmap。你可以在numpy documentation中閱讀更多關於它的信息。

當您創建np.memmap時,可以使用offset參數爲該標頭預留空間。注:文檔指定的報頭長度應該是16的倍數:

比方說,你預留5 * 16 = 80個字節的報頭(詳見下文):

import numpy as np 
x = np.memmap('/tmp/x.npy', mode='w+', dtype=np.ubyte, shape=(int(1E10),), offset=80) 

然後,當完成後操縱MEMMAP,您創建並寫入頭,採用np.lib.format

header = np.lib.format.header_data_from_array_1_0(x) 

with open('/tmp/x.npy', 'r+b') as f: 
    np.lib.format.write_array_header_1_0(f, header) 

注意,這把從MEMMAP文件開始的頭,所以如果len(header) > 80,那麼它將覆蓋部分數據,你的文件將會是n不可讀。標題是一個固定長度的魔術字符串,兩個版本字節,兩個字節指定標題長度,以及一個字典的字符串表示形式,指定'形狀','descr'和'順序'。如果您知道陣列的形狀和dtype(descr),則可以輕鬆計算標題長度(爲了簡單起見,我將其固定在80以上)。

寫頭後,您可以使用np.load加載數據:

y = np.load('/tmp/x.npy')