2015-05-08 100 views
8

我有一個包含平面位置記錄的二進制文件。 每個記錄看起來像:使用Numpy fromfile和給定的偏移量讀取二進制文件

0x00: Time, float32 
0x04: X, float32 // X axis position 
0x08: Y, float32 // Y axis position 
0x0C: Elevation, float32 
0x10: float32*4 = Quaternion (x,y,z axis and w scalar) 
0x20: Distance, float32 (unused) 

因此,每個記錄是32字節長。

我想要一個Numpy數組。

在偏移1859處有一個無符號整數32(4個字節),它表示數組的元素個數。 12019在我的情況。

我不關心(現在)的標題數據(前偏移1859)

陣列僅開始於1863年的偏移(= 1859 + 4)。

我定義我自己numpy的D型像

dtype = np.dtype([ 
    ("time", np.float32), 
    ("PosX", np.float32), 
    ("PosY", np.float32), 
    ("Alt", np.float32), 
    ("Qx", np.float32), 
    ("Qy", np.float32), 
    ("Qz", np.float32), 
    ("Qw", np.float32), 
    ("dist", np.float32), 
]) 

而且我閱讀使用fromfile文件:

a_bytes = np.fromfile(filename, dtype=dtype) 

但我看不出有任何參數,以提供fromfile通過抵消。

回答

9

您可以打開標準python文件打開文件,然後設法跳過標題,然後將文件對象傳遞到fromfile。這樣的事情:

import numpy as np 
import os 

dtype = np.dtype([ 
    ("time", np.float32), 
    ("PosX", np.float32), 
    ("PosY", np.float32), 
    ("Alt", np.float32), 
    ("Qx", np.float32), 
    ("Qy", np.float32), 
    ("Qz", np.float32), 
    ("Qw", np.float32), 
    ("dist", np.float32), 
]) 

f = open("myfile", "rb") 
f.seek(1863, os.SEEK_SET) 

data = np.fromfile(f, dtype=dtype) 
print x 
+3

謝謝。它解決了我的問題。我也注意到'data = np.memmap(filename,dtype = dtype,mode ='r',offset = offset_array,shape = N)' ' – scls

+1

對,如果它是一個大文件,那麼memmap可能是走。 – reptilicus

2

我遇到了類似的問題,但上述答案都沒有讓我滿意。 我需要實現類似虛擬表的數據量非常大的二進制記錄,這可能會佔用比我在一個numpy數組中所能承受的更多內存。所以我的問題是如何讀/寫二進制文件中的一小部分整數 - 文件的一個子集到numpy數組的子集中。

這是爲我工作的解決方案:

import numpy as np 
recordLen = 10 # number of int64's per record 
recordSize = recordLen * 8 # size of a record in bytes 
memArray = np.zeros(recordLen, dtype=np.int64) # a buffer for 1 record 

# Create a binary file and open it for write+read 
with open('BinaryFile.dat', 'w+b') as file: 
    # Writing the array into the file as record recordNo: 
    recordNo = 200 # the index of a target record in the file 
    file.seek(recordSize * recordNo) 
    bytes = memArray.tobytes() 
    file.write(bytes) 

    # Reading a record recordNo from file into the memArray 
    file.seek(recordSize * recordNo) 
    bytes = file.read(recordSize) 
    memArray = np.frombuffer(bytes, dtype=np.int64).copy() 
    # Note copy() added to make the memArray mutable 
相關問題