Was ist das Äquivalent von ‚fread‘ von Matlab in Python?
Frage
Ich habe praktisch keine Kenntnisse von Matlab, und Notwendigkeit, einige Parsing-Routinen in Python zu übersetzen. Sie sind für große Dateien, die selbst sind unterteilt in ‚Blöcke‘, und ich habe Schwierigkeiten, direkt aus dem Off mit der Prüfsumme am Anfang der Datei.
Was genau geht hier in 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 ist die Datei, die gerade betrachtet wird, iBlock ist ein Zähler für die ‚Block‘ Sie innerhalb der Datei sind in
magic_l und magic_h sind mit Prüfsummen später zu tun, hier ist der Code für die (folgt direkt aus dem Code oben):
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));
- Was mit dem
%08X
los ist und diehex2dec
Sachen? - Auch, warum geben Sie
3*4
statt12
?
Wirklich obwohl, möchte ich wissen, wie [A, count] = fread(fid, 3, 'uint32');
in Python zu replizieren, wie io.readline()
gerade ist, um die ersten drei Zeichen der Datei ziehen. Entschuldigt, wenn ich vermisse den Punkt irgendwo hier. Es ist nur, dass io.readline(3)
mit auf der Datei etwas zurück scheint es nicht sollte, und ich verstehe nicht, wie die block_length
in einem einzigen Byte passen können, wenn es möglicherweise sehr lange sein könnte.
Vielen Dank für diesen Streifzug zu lesen. Ich hoffe, Sie Art verstehen können, was ich wissen will! (Einsicht in alle sehr geschätzt wird.)
Lösung
Von der Dokumentation von fread
, es ist eine Funktion Binärdaten zu lesen. Das zweite Argument gibt die Größe des Ausgangsvektors, die dritte die Größe / Art der Elemente gelesen werden.
Um dies in Python zu erstellen, können Sie mit dem array
Modul:
f = open(...)
import array
a = array.array("L") # L is the typecode for uint32
a.fromfile(f, 3)
Dies wird drei Uint32 Werte aus der Datei f
lesen lesen, die anschließend in a
zur Verfügung stehen. Aus der Dokumentation von fromfile
:
Read n Artikel (als Maschinen Wert) aus dem Dateiobjekt F und hängen sie an das Ende des Arrays. Wenn weniger als n Elemente verfügbar sind, wird EOFError angehoben, aber die Elemente, die verfügbar waren, sind nach wie vor in die Anordnung eingelegt. f müssen echte integrierte Dateiobjekt sein; etwas anderes mit einer Lese () -Methode nicht tun.
Arrays die Sequenz Protokoll implementieren und damit die gleichen Operationen wie Listen unterstützen, aber Sie können auch die .tolist()
Methode verwenden, um eine normale Liste aus dem Array zu erstellen.
Andere Tipps
Python-Code für das Lesen eines 1-dimensionalen Array
Wenn Matlab mit Python ersetzen wollte ich binäre Daten in ein numpy.array
, so dass ich verwenden numpy.fromfile
die Daten in ein 1-dimensionales zu lesen Array:
import numpy as np
with open(inputfilename, 'rb') as fid:
data_array = np.fromfile(fid, np.int16)
Einige Vorteile der Verwendung von numpy.fromfile
im Vergleich zu anderen Python-Lösungen gehören:
- Nicht manuell mit auf die Anzahl der Elemente bestimmen zu lesen. Sie können sie mit dem
count=
Argument angeben, aber es standardmäßig-1
, die die gesamte Datei anzeigt, zu lesen. -
Die Möglichkeit, entweder ein offenes Dateiobjekt zu spezifizieren (wie ich oben mit
fid
tat) oder Sie können einen Dateinamen angeben. Ich ziehe ein offenes Dateiobjekt verwenden, aber wenn Sie einen Dateinamen verwenden möchten, können Sie die beiden Zeilen oben ersetzen:data_array = numpy.fromfile(inputfilename, numpy.int16)
Matlab-Code für einen 2-dimensionalen Array
Matlab fread
hat die Fähigkeit, die Daten in eine Matrix von Form [m, n]
zu lesen, anstatt es einfach in einen Spaltenvektor zu lesen. Zum Beispiel Daten in eine Matrix mit 2 Zeilen lesen verwenden:
fid = fopen(inputfilename, 'r');
data_array = fread(fid, [2, inf], 'int16');
fclose(fid);
Equivalent Python-Code für einen 2-Dimensional Array
Sie können dieses Szenario in Python behandeln Numpy des shape
und transpose
verwendet wird.
import numpy as np
with open(inputfilename, 'rb') as fid:
data_array = np.fromfile(fid, np.int16).reshape((-1, 2)).T
- Die
-1
sagtnumpy.reshape
schließen die Länge des Arrays für das Dimension basierend auf der anderen Dimension-das Äquivalent voninf
unendlich Darstellung des Matlab. - Die
.T
transponiert die Anordnung so, dass es ein 2-dimensionales Feld mit der ersten Dimension ist-der-Achse mit einer Länge von 2.
Wirklich obwohl, ich möchte wissen, wie
[A, count] = fread(fid, 3, 'uint32');
zu replizieren
In Matlab, einer der fread()
Unterschriften ist fread(fileID, sizeA, precision)
. Diese liest die ersten sizeA
Elemente (nicht Bytes) eine Datei, die jeweils eine Größe für precision
ausreichend. In diesem Fall, da Sie lesen in uint32
, jedes Element der Größe 32 Bits oder 4 Bytes.
Also, stattdessen versuchen io.readline(12)
die ersten 3 4-Byte-Elemente aus der Datei zu erhalten.
Der erste Teil von Torsten Antwort bedeckt ist ... Sie Bedarf array
oder numarray
sowieso nichts mit diesen Daten zu tun.
Wie für das% 08X und die HEX2DEC Sachen,% 08X ist nur das Druckformat für die UNIT32 Zahlen (8-stellige hex, genau die gleiche wie Python) und HEX2DEC ( '4D445254') ist Matlab für 0x4D445254.
Schließlich ~ = in Matlab ist eine bitweise vergleichen; Verwendung == in Python.