Что такое эквивалент "fread" из Matlab в Python?
я практически не знаю Matlab, и мне нужно перевести некоторые процедуры синтаксического анализа на Python. Они предназначены для больших файлов, которые сами разделены на "блоки", и у меня возникают трудности с контрольной суммой в верхней части файла.
что именно происходит здесь в MATLAB?
status = fseek(fid, 0, 'cof');
fposition = ftell(fid);
disp(' ');
disp(['** Block ',num2str(iBlock),' File Position = ',int2str(fposition)]);
% ----------------- Block Start ------------------ %
[A, count] = fread(fid, 3, 'uint32');
if(count == 3)
magic_l = A(1);
magic_h = A(2);
block_length = A(3);
else
if(fposition == file_length)
disp(['** End of file OK']);
else
disp(['** Cannot read block start magic ! Note File Length = ',num2str(file_length)]);
end
ok = 0;
break;
end
fid-это файл, который в настоящее время просматривается iBlock-это счетчик, для которого вы находитесь в файле
magic_l и magic_h должны сделать с контрольными суммами позже, Вот код для этого (следует прямо из кода выше):
disp(sprintf(' Magic_L = %08X, Magic_H = %08X, Length = %i', magic_l, magic_h, block_length));
correct_magic_l = hex2dec('4D445254');
correct_magic_h = hex2dec('43494741');
if(magic_l ~= correct_magic_l | magic_h ~= correct_magic_h)
disp(['** Bad block start magic !']);
ok = 0;
return;
end
remaining_length = block_length - 3*4 - 3*4; % We read Block Header, and we expect a footer
disp(sprintf(' Remaining Block bytes = %i', remaining_length));
- что происходит с
%08X
иhex2dec
вещи? - кроме того, зачем указывать
3*4
вместо12
?
на самом деле, я хочу знать, как реплицировать [A, count] = fread(fid, 3, 'uint32');
в Python, как io.readline()
просто тянет первые 3 символа файла. Извини,если я упустил суть. Просто используя io.readline(3)
в файле, кажется, возвращается что-то, что он не должен, и я не понимаю, как block_length
может поместиться в один байт, когда он потенциально может быть очень длинным.
Спасибо за чтение этой бессвязной. Надеюсь, вы понимаете, что я хочу знать! (Любое понимание вообще приветствуется.)
4 ответов
С документация fread
, это функция для чтения двоичных данных. Второй аргумент задает размер выходного вектора, третий-размер/тип считываемых элементов.
чтобы воссоздать это в Python, вы можете использовать array
модуль:
f = open(...)
import array
a = array.array("L") # L is the typecode for uint32
a.fromfile(f, 3)
это будет читать читать три значения uint32 из файла f
, которые имеются в a
далее. Из документации fromfile
:
прочитайте n элементов (как значения машины) из объекта файла f и добавьте их в конец массива. Если доступно менее n элементов, вызывается EOFError, но элементы, которые были доступны, по-прежнему вставляются в массив. f должен быть реальным встроенным файловым объектом; что-то еще с методом read() не будет делать.
массивы реализуют протокол последовательности и поэтому поддерживают те же операции, что и списки, но вы можете также используйте .tolist()
метод для создания нормального списка из массива.
код Python для чтения 1-мерного массива
при замене Matlab на Python я хотел прочитать двоичные данные в numpy.array
и numpy.fromfile
для чтения данных в 1-мерный массив:
import numpy as np
with open(inputfilename, 'rb') as fid:
data_array = np.fromfile(fid, np.int16)
преимущества использования numpy.fromfile
по сравнению с другими решениями Python включают в себя:
- нет необходимости вручную определять количество элементов для чтения. Вы можете указать их с помощью
count=
аргумент, но по умолчанию он равен-1
что указывает на чтение всего файла. -
возможность указать либо открытый объект файла (как я сделал выше с
fid
) или вы можете указать имя файла. Я предпочитаю использовать объект open file, но если вы хотите использовать имя файла, вы можете заменить две строки выше:data_array = numpy.fromfile(inputfilename, numpy.int16)
код Matlab для двумерного массива
Матлаб-х fread
обладает способностью считывать данные в матрица формы [m, n]
вместо того, чтобы просто читать его в вектор-столбец. Например, для считывания данных в матрицу с 2 строк:
fid = fopen(inputfilename, 'r');
data_array = fread(fid, [2, inf], 'int16');
fclose(fid);
эквивалентный код Python для 2-мерного массива
вы можете обрабатывать этот сценарий на языке Python с использованием библиотеки numpy это shape
и transpose
.
import numpy as np
with open(inputfilename, 'rb') as fid:
data_array = np.fromfile(fid, np.int16).reshape((-1, 2)).T
- на
-1
говоритnumpy.reshape
чтобы вывести длину массива для этого измерения на основе другого измерения-эквивалента представление бесконечности. - на
.T
транспонирует массив таким образом, что он представляет собой 2-мерный массив с первым измерением-осью-длиной 2.
На самом деле, я хочу знать, как реплицировать
[A, count] = fread(fid, 3, 'uint32');
в Matlab, один из fread()
's подписи fread(fileID, sizeA, precision)
. Это читается в первом sizeA
элементы (не байты) файла, каждый из которых имеет размер, достаточный для precision
. В этом случае, так как Вы читаете в uint32
, каждый элемент имеет размер 32 бита, или 4 байта.
поэтому вместо этого попробуйте io.readline(12)
чтобы получить первые 3 4-байтовых элемента из файла.
первая часть покрыта ответом Торстена... вам понадобится array
или numarray
делать что-нибудь с этими данными в любом случае.
Что касается %08X и материала hex2dec, %08X - это просто формат печати для этих чисел unit32 (8-значный hex, точно такой же, как Python), а hex2dec ('4D445254') - matlab для 0x4D445254.
наконец, ~ = в matlab-это побитовое сравнение; используйте == в Python.