2016-08-06 4 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().

Но если вы заранее знаете полный макет файла, вы можете предварительно распределить массив, а затем использовать fromfile и seek для чтения блоков 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