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 die hex2dec Sachen?
  • Auch, warum geben Sie 3*4 statt 12?

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.)

War es hilfreich?

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 sagt numpy.reshape schließen die Länge des Arrays für das Dimension basierend auf der anderen Dimension-das Äquivalent von inf 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top