Verfasst am: 25.01.2013, 01:31
Titel: Cells und ihre Probleme (vor allem: in Matrix schreiben)
Hallo!
Ich bin langsam am verzweifeln ...
Folgendes Problem:
Ich muss Datensätze einlesen. Das Programm läuft gut - bis zur letzten Zeile! Dort wird eine völlig idente Zeile plötzlich anders eingelesen.
Jeder Block sieht gleich aus - bis auf die Länge. Diese steckt in der fetten Zahl - eine "Zeile" entspricht 8 Werten, dh diese werden in der Zeile darunter fortgesetzt. Es könnten aber auch 10 Werte sein - das hängt von anderen Parametern ab, in diesem Fall aber können wir von 8 Werten ausgehen. Habe also eine if-Bedingung eingefügt, dass wenn es zwischen 5 und 10 Werten liegt, der folgende Code ausgeführt werden soll:
Hier mein Problem: Die ersten 44 Blöcke funktionieren alles perfekt. Auf die beiden leeren Werte wird automatisch NaN geschrieben. Jedoch nicht in der allerletzten Zeile. Hier werden diese Werte strikt ignoriert. (Auf Whitespaces habe ich überprüft - wirklich haargenau gleich!)
Mein Code erscheint wahrscheinlich grausam. Wollte eigentlich direkt einen String mit String{1:5}(1:2) = NaN erstellen, erhalte aber nur eine Fehlermeldung.
Aber trotz bestehenden String mit NaN's - nach Einlesen meiner Zeile aus dem File mit textscan wirde umstrukturiert und aus meinem schönen CellArray mit {1:5} Cells und je (1:2) Spalten wurde wieder eine {1:5} CellArray mit (1:2) Spalten für nur 3 Cells. Die letzten beiden erhalten also nur noch einen Wert (1 x 1) und meine NaN's wurden somit herausgelöscht/überschrieben.
Ich brauche auf alle Fälle eine Matrix - also bitte keine Belehrungen, dass das nicht sinnvoll is ...
Also lange Rede, kurzer Sinn:
Ich suche einen Befehl/Code mit dem ich eine Matrix (2 x 5) mit NaN gefüllt erstellen kann und anschließend mit den Werten des CellArray {5 * 1 x 2} überschrieben werden kann und ich somit am Ende immer noch eine Matrix mit (2 x 5) habe, die an den Stellen, wo das CellArray "leer" war, immer noch NaN stehen hat.
bitte reproduzierbaren Beispielcode und die Beispieldatei anhängen, damit Abweichungen aufgrund minimaler Unterschiede in der Datei als Ursache ausgeschlossen werden können.
Die ersten beiden Codezeilen haben keinen Einfluss auf den Wert der Variable String am Ende, da diese Variable in der Zeile darauf überschrieben wird. Das sollte übrigens auch im Editor als Warnung orange angezeigt werden.
Habe gerade nachgeschaut - mein Problem führt daher, dass ich eine Leerzeile gelöscht habe. Welche aber im Dateistandard eigentlich gegeben ist und ich gar nicht löschen dürfte.
Habe aber jetzt immer noch ein Problem:
Erhalte jetzt eine Leerzeile, dh feof ist hier nutzlos.
Würde also gerne überprüfen ob ein 0-CellArray eingelesen wurde, wenn ja sollte man bitte aus der Funktion aussteigen und in die Mainfunktion zurückkehren.
Datenstruktur bleibt die gleiche, es wird nur die letzte Zeile zuerst eingelesen. Diese Zeile gilt es auch zu überprüfen. Sobald sie keine Daten enthält, aber erstellt wurde, sollte man in die Main zurück.
Habe es mit return versucht, aber das funktioniert nicht so wie ich will - außer ich verwende es falsch. Problem natürlich auch die wahrscheinlich falsche Verwendung der Umwandlung des CellArrays, also:
Im folgenden Code stecke ich wieder beim Gleichen: Wie wandle ich einen CellArray um?
cell2mat funktioniert nicht, weil verschiedene Datentypen in meiner cell sind.
Der "DataString" liest sobald die Funktion geöffnet wird, die erste Zeile aus.
Diese wird dann bearbeitet usw.
Die allerletzte Zeile des Files ist leer. Wird aber trotzdem eingelesen - natürlich funktioniert der restliche Code mit dem leeren CellArray nicht mehr. Somit ist diese leere Zeile die flag, dass jetzt das File endet - und ich kann nicht feof verwenden, weil die Datei ja erst NACH der leeren Zeile endet. Ich muss das aber irgendwie überprüfen. Das sollte mein Code bezwecken - aber wie man vielleicht schon herausliest, funktioniert das nicht.
Ich möchte aus meiner Unterfunktion zurück in mein Mainprogramm - mit return sollte das ja eigentlich irgendwie funktionieren.
Dh ich suche eine Möglichkeit mein leeres CellArray, das daher stammt dass eine leere Zeile eingelesen wurde, zu überprüfen ob es leer ist ... Wenn ja, dann zurück in die Mainfunktion.
Und ja, ich meine das gesamte Array, weil ja nur eine einzige Zeile in dem gesamten File wirklich gänzlich leer ist ..
wollte nur mal loswerden, dass mein Code aus Deinem ersten Thread zu diesem Dateiformat alle Deine hier beschriebenen Probleme mit regulären Ausdrücken umgeht.
Okay, ich danke schon mal für die Hilfe, aber noch sind wir nicht ganz bei der Lösung des Problems.
Ich versuche mich ganz klar und deutlich auszudrücken, ich weiß ich bin nicht gerade ein Genie komplexe Aufgabenstellungen klar und deutlich wiederzugeben:
Ich habe eine Funktion die mir meine Daten aus dem File ausliest, jeweils ein Block (siehe Entry 1). Die erste Zeile des Blocks wird mit dem DataString (siehe Code Entry zuvor) herausgelesen und ist somit als CellArray abgespeichert. Die Funktion schickt kein FileHandle an meine Mainfunktion zurück, dh sie "merkt" sich also selbst wo sie steht (typisch Matlab eben (.
Das File das ich einlese ist internationaler Standard, dh auch diese leere Zeile ganz am Ende des Files kommt bei jedem File dieser Art vor (normalerweise). Meine Funktion hat also nun den letzten Block eingelesen und wird nochmals aufgerufen und kommt zu eben dieser leeren Zeile, die ich als Abbruchbedingung verwenden will. (Wie erwähnt feof funktioniert nicht, weil das File erst endet nachdem diese leere Zeile eingelesen wurde.
Diese Abbruch- bzw. Returnbedingung sollte eben den eingelesenen CellArray überprüfen ob sie gänzlich leer ist. isempty funktioniert nicht mit CellArrays, und meine Umwandlung in ein geeignetes Format (also muss keine Matrix sein), dass überprüft werden kann ob es leer ist oder Daten beinhaltet.
Mit meinem Befehl "checkData = [DataString{:}]" versuchte ich also das umzuwandeln und somit abzufragen, aber leider wird daraus nur wieder eine weitere CellArray.
Das sind also die Probleme:
1. Irgendwie funktioniert es kaum (ich sage nicht nie), dass meine CellArray in eine andere Datenstruktur umgewandelt wird - und ich glaube mittlerweile, dass ich es wahrscheinlich einfach falsch anwende.
2. Ich habe aufgrund des 1. Problems keine Möglichkeit gefunden zu überprüfen, ob ich eine leere CellArray besitze. Somit komme ich natürlich nicht zum return (was mich hoffentlich in meine Hauptfunktion zurückführt!?).
Die Frage also:
Wie kann ich untersuchen ob mein CellArray leer ist, so dass endlich mein return in Kraft tritt??
Abschließend möchte ich noch erklären, was ich bereits versucht habe - und wo ich glaube, dass noch ein Problem steckt:
Ich habe versucht den CellArray zu auf "Leere" zu überprüfen (also wie oben beschrieben). Wie erwähnt funktioniert feof nicht beim Fileaufruf, dachte aber, dass es vielleicht funktionieren könnte, sobald ich DataString eingelesen habe. Aber nein ...
Entweder macht return was es nicht sollte und schreibt einfach einen error raus (japp, genau um mich zu ärgern ...) und kommt also nicht wie gewollt zurück in die main um dort weiterarbeiten zu können.
Hier noch der Code mit Aufruf in der main und der Teil mit der Abbruchbedingung - Verschiedenstes ausprobiert.
Code:
% Main while1 [ObsData, ObsTime, SatCount] = ReadData(fileID, ObsDataHeader); % Aufruf Observation File zum Auslesen -
[Time ObsDataBody] = MatrixDesigner(ObsData, ObsTime, Time, ObsDataBody); % Funktion zum Matrizen erstellen end % Nach Beenden des Auslesens will ich die Whileschleife beenden und mein Programm weiterausführen ...
% checkData = [DataString{:}]; % Wird nicht in Matrix, double oder ähnliches verwandelt % if all(isempty(checkData)) % Überprüfung auf "Leere" (auch mit Input DataString schon versucht % return; % end
%iffeof(fileID)% Überprüfung ob fileID vl. jetzt beendet? % return
%end
und das hier ist der error den ich im Augenblick erhalte:
Error inReadData (line 12)
DataString = textscan(fileID, '%d %d %d %d %9.7f %d %d%s', 1, 'delimiter', ''); (tritt beim allerletzten Aufruf auf)
_________
Sirius3 hat Folgendes geschrieben:
wollte nur mal loswerden, dass mein Code aus Deinem ersten Thread zu diesem Dateiformat alle Deine hier beschriebenen Probleme mit regulären Ausdrücken umgeht.
Leider nicht. Da ich eine vorgegebene Funktionsstruktur in meinem Assignment habe.
Muss einen FileHandle zurückgeben, nachdem ich den Header ausgelesen habe (was ohne Probleme funktioniert). Außer ich habe deinen Code nicht richtig verstanden.
Auch ansonsten ist das Programm fertig, wenn ich nur endlich eine Bedingung finde, wie ich aus meiner Funktion zurück in die Main hüpfe und dort weitermachen kann sobald das File geendet hat
Habe jetzt die Abbruchbedingung (danke Sirus, mit cellfun hast du mich darauf gebracht) gefunden. Und hatte sie wahrscheinlich schon lange vorher mit einer meiner anderen Bedingungen auch ...
Also nach gründlicher Überprüfung:
Ich komme in die Bedingung rein. Es wird return ausgeführt ... und Fehlermeldung:
Error in ReadData (line 9)
DataString = textscan(fileID, '%d %d %d %d %9.7f %d %d%s', 1, 'delimiter', '');
Output argument "ObsData" (and maybe others) not assigned during call to "D:\...\ReadData.m>ReadData".
Error in Programm (line 38 )
[ObsData, ObsTime, SatCount] = ReadData(fileID, ObsDataHeader); % Aufruf Observation File zum Auslesen
Dh kaum returne ich zu meiner While-Schleife gibt's diesen Fehler. Entweder er geht trotzdem nochmals in die Schleife rein, oder keine Ahnung ...
Hab gerade mit globalen Variablen gespielt, selbst dann bekomme ich den gleichen Fehler, obwohl ich damit eine Abbruchbedingung erstellt hätte.
Eine ziemlich ungewöhnliche Frage: Gibt's jemanden, der sich gut auskennt und dem ich meinen Code schicken und der sich 10 Minuten Zeit nehmen könnte das durchzusehen? Arbeite am gleichen Problem mittlerweile seit Stunden (ohne Übertreibung) und mache kaum Fortschritte. Irgendwo muss doch der Fehler liegen!
es wäre sehr hilfreich, wenn du auf die Fragen an dich eingehst.
Die Fehlermeldung besagt klar und deutlich, wo das Problem liegt: in readData.m wird das Ausgabeargument obsData nicht definiert. Schau dir im Code an, woran das liegen kann, ggf. mit Haltepunkt.
An das hätte ich nie gedacht, ich habe immer nur auf den Pfad und die Line in der der Fehler passiert ist in der Fehlermeldung geachtet, aber nicht verstanden worum es wirklich geht, man lernt nie aus!
Musste natürlich noch die Rückgabewerte (mit NaN) definieren bevor ich return anwende! (Im Nachhinein gesehen äußerst logisch)
DANKE!
PS: Versuche doch eigentlich auf die Fragen einzugehen ... Muss kurz und präzise noch lernen ...
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.