2016-08-06 70 views
0

我想使用單個numpy.fromfile調用讀取二進制文件中的不同塊。每個塊的格式如下:使用numpy.fromfile讀取分散的二進制數據

OES=[ 
('EKEY','i4',1), 
('FD1','f4',1), 
('EX1','f4',1), 
('EY1','f4',1), 
('EXY1','f4',1), 
('EA1','f4',1), 
('EMJRP1','f4',1), 
('EMNRP1','f4',1), 
('EMAX1','f4',1), 
('FD2','f4',1), 
('EX2','f4',1), 
('EY2','f4',1), 
('EXY2','f4',1), 
('EA2','f4',1), 
('EMJRP2','f4',1), 
('EMNRP2','f4',1), 
('EMAX2','f4',1)] 

這裏是二進制的格式:

Data I want (OES format repeating n times) 
------------------------ 
Useless Data 
------------------------ 
Data I want (OES format repeating m times) 
------------------------ 
etc.. 

我知道我想要的數據和無用的數據之間的字節增量。我也知道我想要的每個數據塊的大小。

到目前爲止,我已經通過文件對象f,然後調用來完成我的目標:

nparr = np.fromfile(f,dtype=OES,count=size) 

所以我對每一個數據塊我想不同的nparr和所有numpy陣列連接成一個新陣列。

我的目標是有一個單一的數組與我想要的所有塊沒有連接(爲了記憶的目的)。也就是說,我只需撥打nparr = np.fromfile(f,dtype=OES)一次。有沒有辦法實現這個目標?

回答

2

也就是說,我只想撥打nparr = np.fromfile(f,dtype=OES)一次。有沒有辦法實現這個目標?

不,沒有一個電話打到fromfile()

但是,如果您事先知道文件的完整佈局,則可以預先分配陣列,然後使用fromfileseek將OES塊直接讀入預分配陣列。例如,假設您知道每個OES塊的文件位置,並且知道每個塊中的記錄數。也就是說,你知道:

file_positions = [position1, position2, ...] 
numrecords = [n1, n2, ...] 

然後,你可以做這樣的事情(假設f是已打開的文件):

total = sum(numrecords) 
nparr = np.empty(total, dtype=OES) 
current_index = 0 
for pos, n in zip(file_positions, numrecords): 
    f.seek(pos) 
    nparr[current_index:current_index+n] = np.fromfile(f, count=n, dtype=OES) 
    current_index += n 
+0

非常感謝您!我也在考慮這個。我對內存的管理方式有些模糊。這不會導致從np.fromfile和nparr重複的內存? nparr子集是否是np.fromfile的視圖?還是一個副本?根據我的測試,似乎像這樣的項目分配似乎正在複製。但我可能是錯的。謝謝你的建議。 – snowleopard

+1

對於每個塊,fromfile(f,count = n,dtype = OES)將創建一個長度爲「n」的數組。然後,該數組將被複制到'nparr'中的適當範圍內。 'fromfile'創建的數組不會被分配到其他地方,所以它的內存可以被python重用。 –

+0

你的意思是不可用?根據我對python的垃圾收集器的閱讀,如果這就是你的意思,那將是非常有意義的。 – snowleopard