Gleitkommazahlgröße in einer funktionsumschlossenen sscanf-Anweisung dynamisch angeben

Ich habe eine strukturierte Datendatei, die aus Kopfzeilen besteht, die mit Datenblöcken durchsetzt sind. Ich lese jeden Datenblock (wie durch die Kopfzeile definiert) in eine separate Zelle eines Zellenarrays. Angenommen, nach dem Laden der Daten mittextscanIch habe ein Zellenarrayx und ein Array von Indizes von Kopfzeilen und EOF (headerIdx) des folgenden Formulars:

x={'header line 1';'98.78743';'99.39717';'99.93578';'100.40125';'100.79166';'101.10525';'101.34037';'101.49553';'101.56939';'101.56072';'101.4685';'101.29184';'101.03002';'100.68249';'header line 2';'100.24887';'99.72897';'99.12274';'98.43036';'97.65215';'96.78864';'95.84054';'header line 3';'3.2';'4.31';'2.7';'4.6';'9.3'};
headerIdx=[1;16;24;30];

Ich versuche dann, jeden Datenblock unter einer Kopfzeile in ein separates Element eines Zellenarrays zu extrahierensscanf undstr2mat (wie vorgeschlagen vondieser Beitrag). Anfangs schlug dieser Ansatz fehl, weil die Elemente innerhalb eines bestimmten Datenblocks unterschiedlich lang waren. Dies kann durch Einfügen eines numerischen Flags für das gelöst werden'%f' Argument zu helfensscanf wissen, wo die Eingabedaten abzugrenzen sind (wie von vorgeschlagen)dieser Beitrag). Man kann dann eine Strategie wie die folgende anwenden, um die Umwandlung strukturierter Daten in ein Zellenfeld blockspezifischer Doppelfelder zu bewirken:

extract_data = @(n) sscanf(str2mat(x(headerIdx(n)+1:headerIdx(n+1)-1)).',['%' num2str(size(str2mat(x(headerIdx(n)+1:headerIdx(n+1)-1)).',1)) 'f']);
extracted_data = arrayfun(extract_data,1:numel(headerIdx)-1,'UniformOutput',false);

Das numerische Flag der Formatzeichenfolge kann entweder auf eine beliebige Größe festgelegt werden, um alle Daten zu umfassen, oder es kann blockspezifisch festgelegt werden, wie im obigen Beispiel. Letzterer Ansatz führt zu einer redundanten Auswertung vonstr2mat (einmal für die Eingabe ansscanf und einmal für die Eingabe in die'%f' String-Generator. Kann diese Redundanz vermieden werden, ohne dass Schleifenanweisungen verwendet werden, in denen die Ausgabe von gespeichert wird?str2mat Befehl in einer temporären Variablen? Beachten Sie, dass man nicht einfach die Ausgabe dessize Befehl, der auf die Ausgabe von angewendet wirdstr2mat(x).' auf dem gesamten Datensatz, da die Kopfzeilen im Allgemeinen die Zeilen mit der größten Anzahl von Zeichen sein werden.

Endlich habe ich das gebautx obige Matrix, um die Tatsache widerzuspiegeln, dass einige Datenblöcke eine andere Genauigkeit aufweisen können als andere Blöcke. Dies ist der Grund, den Formatstring blockspezifisch zu setzen. Meine Tests haben gezeigt, dass trotz genauer Konstruktion eines blockspezifischen Formatstrings (['%' num2str(size(str2mat(x(headerIdx(n)+1:headerIdx(n+1)-1)).',1)) 'f']), die Daten in allen Elementen des resultierenden Zellenarrays (extracted_data) sind letztendlich gezwungen, die gleiche Präzision zu haben (siehe unten). Warum ist das so und wie kann es korrigiert werden?

extracted_data{:}

ans =

   98.7874
   99.3972
   99.9358
  100.4013
  100.7917
  101.1052
  101.3404
  101.4955
  101.5694
  101.5607
  101.4685
  101.2918
  101.0300
  100.6825


ans =

  100.2489
   99.7290
   99.1227
   98.4304
   97.6522
   96.7886
   95.8405


ans =

    3.2000
    4.3100
    2.7000
    4.6000
    9.3000

Antworten auf die Frage(0)

Ihre Antwort auf die Frage