2015-07-03 124 views
6

我想讀取Python中的二進制文件,其準確的佈局存儲在二進制文件本身。如何使用`np.fromfile`從二進制文件中讀取連續數組?

該文件包含一個二維數組序列,每個數組的行和列維存儲爲其內容之前的一對整數對。我想連續讀取文件中包含的所有數組。

我知道這可以用f = open("myfile", "rb")f.read(numberofbytes)來完成,但是這很笨拙,因爲那時我需要將輸出轉換爲有意義的數據結構。我想用numpy的np.fromfile自定義dtype,但還沒有找到一種方法來讀取文件的一部分,保持打開狀態,然後繼續閱讀修改的dtype

我知道我可以使用osf.seek(numberofbytes, os.SEEK_SET)np.fromfile多次,但是這將在文件中圍繞意味着很多不必要的跳躍。

總之,我想MATLAB的fread(或至少像C++ ifstreamread)。

這樣做的最好方法是什麼?

+0

你能描述一下文件的格式嗎?在不瞭解文件本身的情況下很難推薦一種特定的方法。 –

+0

它是一個原始的二進制文件,它包含來自C++程序的雙精度矩陣,以及描述矩陣大小的整數 – jacob

+0

單個文件是否包含多個數組,或者每個文件只有一個數組?數組的大小是否在文件開頭的標題中給出?你能描述標題嗎? –

回答

4

您可以將打開的文件對象傳遞到np.fromfile,讀取第一個數組的維度,然後讀取數組內容(再次使用np.fromfile),併爲同一文件中的其他數組重複此過程。

例如:

import numpy as np 
import os 

def iter_arrays(fname, array_ndim=2, dim_dtype=np.int, array_dtype=np.double): 

    with open(fname, 'rb') as f: 
     fsize = os.fstat(f.fileno()).st_size 

     # while we haven't yet reached the end of the file... 
     while f.tell() < fsize: 

      # get the dimensions for this array 
      dims = np.fromfile(f, dim_dtype, array_ndim) 

      # get the array contents 
      yield np.fromfile(f, array_dtype, np.prod(dims)).reshape(dims) 

用法示例:

# write some random arrays to an example binary file 
x = np.random.randn(100, 200) 
y = np.random.randn(300, 400) 

with open('/tmp/testbin', 'wb') as f: 
    np.array(x.shape).tofile(f) 
    x.tofile(f) 
    np.array(y.shape).tofile(f) 
    y.tofile(f) 

# read the contents back 
x1, y1 = iter_arrays('/tmp/testbin') 

# check that they match the input arrays 
assert np.allclose(x, x1) and np.allclose(y, y1) 

如果陣列是大的,你可以考慮使用np.memmap與地方np.fromfileoffset=參數,以獲得數組的內容作爲內存映射而不是將它們加載到RAM中。