Problem: Einlesen einer Datei < Matlab < Mathe-Software < Mathe < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 19:54 Fr 10.11.2006 | Autor: | CzumA |
Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.
Hallo Matlab Freunde!
Ich selbst bin Matlab-Neuling und habe bereits die ein oder andere Stunde im Internet nach meinem - wahrscheinlich für euch simplen - Problem gesucht, bin aber nicht fündig geworden.
Mein Problem:
Ich habe eine Datei (besitzt keine Endung, ist aber mit dem Editor oder dem WordPad ohne Probleme zu öffnen), welche 5 Spalten und um die 700.000 Zeilen besitzt!
sprich:
x x x x x
x x x x x
x x x x x
x x x x x
..usw
Ich möchte diese Datei nun einlesen und z.B. einen bestimmten der 5 Werte in den einzelnen Zeilen Spalte für Spalte (Schleife?) vergleichen, um extrem hohe Werte finden zu können.
Zum Datei einlesen weiss ich bisher:
fd = fopen('Dateiname.xxx', 'r');
arr = fread(fd, 'integer*2'); % Datei auslesen und Ergebnis in 'arr' speichern
fclose(fd);
Das dies so ohne weiteres nicht funktioniert, kann ich mir gut vorstellen. Ich muss wohl mit einer Matrix arbeiten und die kompletten Daten in diese Matrix schreiben, oder?
Meine Frage nun: Wie? Und wie kann ich, wenn ich meine Daten eingelesen habe, auf die einzelnen Zeilen / Spalten / Werte zugreifen?
Sorry, wenn diese Frage schon behandelt wurde, aber ich habe 28 Seiten Matlab Fragen bei euch durchforstet und mein Problem in diesem SInne nicht gefunden.
Tausend Dank für alle Antworten, die mich weiterbringen und die, die es zumindest versuchen!
MfG
Marc
|
|
|
|
Hallo,
wenn du nur 5 Zahlenspalten importieren willst, dann gibt es eine fertige Lösung in diesem Beitrag.
Es ist zwar ein bisschen mit Kanonen auf Spatzen geschossen, aber es funktioniert. Speichere einfach die angehängte Datei als 'TXTassign.m'.
Der Aufruf in aller Kürze:
TXTassign('Dateiname', {'arr1','arr2','arr3','arr4','arr5'}, ' ', ',');
Das erste Argument klar: dein Dateiname.
Das zweite Argument: Variablennamen für die 5 Spalten, dazu gleich mehr.
Das dritte Argument: dein Spaltentrennzeichen, hier Leerzeichen.
Das vierte Argument: dein Dezimaltrennzeichen, hier ein Komma.
Zusätzlich gibt es weitere zwei hier unwichtige optionale Argumente.
Zu den 5 Variablen: Um die 5 Arrays wieder in einer Matrix zusammenzufassen, kannst du Folgendes machen:
arr = [arr1; arr2; arr3; arr4; arr5]';
Nicht das Apostroph hinter der Klammer vergessen! Sonst hast du 5 Zeilen und 700000 Spalten!
Ich hoffe, es gibt keine Probleme...
Gruß
Martin
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 16:52 Sa 11.11.2006 | Autor: | CzumA |
Hallo!
Erstmal ein DICKES DANKE! an dich... ich werde es mal testen und mich bei Problemen nochmal melden.
MfG
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:48 Mi 15.11.2006 | Autor: | CzumA |
Hallo Martin,
habe nun etwas Zeit gefunden und deinen Lösungsvorschlag getestet, allerdings scheint Matlab (oder mein Rechner ? 1,8Ghz..512mb ram) damit überfordert zu sein.
Habe mal einen Screenshot gemacht:
[Externes Bild http://nap-factory.com/matlab_ausgelastet.JPG]
Wie das Bild zeigt, hab ich zum testen eine kleine Tabelle genommen, mit der auch alles funktionierte. Danach dann selbe Prozedur mit der Originalen Tabelle... nach 3-4 Minuten Ladezeit habe ich abgebrochen..
Es scheint, als sei meine Original Tabelle (übrigens knapp 20MB gross!) etwas zu gross?!
Es handelt sich, wie gesagt, um eine Tabelle mit folgendem Format (ich kopier einfach mal die ersten 10 Zeilen hier rein):
"Valsava2.txt"
3003.000
0.363 1.215 0.008 0.001 0.002
0.362 1.215 0.012 0.002 0.002
0.361 1.214 0.013 0.002 0.002
0.359 1.214 0.013 0.002 0.002
0.363 1.213 0.014 0.001 0.002
0.359 1.213 0.015 0.002 0.002
0.360 1.212 0.013 0.002 0.002
0.360 1.212 0.013 0.001 0.001
0.361 1.212 0.011 0.002 0.002
0.360 1.211 0.010 0.002 0.002
Die Spalten sind durch je durch ein TAB getrennt..
Kann diese "3003.000" in der ersten Zeile ein Problem darstellen ?
Also ich will eigentlich nur alle Zahlen der ersten Spalte, alle der zweiten, alle der dritten usw auf maxima etc überprüfen können ._. Alles seperat.. also bräuchte ich praktisch nur ein Array für Spalte 1 das ich dann z.B. in einer Schleife durchlaufen könnte oder so..
Vielleicht hast du ja noch einen Tip,
Danke im vorraus!
MfG
Marc H.
|
|
|
|
|
Hallo,
bei mir hat diese Funktion über 870MB Speicher verbraucht, bis sie abgeraucht ist...
Macht nix, denn dein Ansinnen ist denkbar einfach. Dafür war meine (wenig effiziente) Funktion nicht ausgelegt.
Viel einfacher geht es mit:
fid = fopen('Valsava2.txt');
daten = fscanf(fid,'%g %g %g %g %g',[5 inf])';
fclose(fid);
Aber du musst vorher auf jeden Fall alles aus der Datei entfernen, was nicht zu den Daten gehört, also auch diese böse erste Zeile!
Gruß
Martin
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 23:30 Mi 22.11.2006 | Autor: | CzumA |
Danke, das funktioniert einwandfrei! Aber gibt es denn eine Möglichkeit, diese erste Zeile vor den eigentlichen Werten zu ignorieren ?
Besten Dank und MfG,
Marc H.
|
|
|
|
|
Hallo,
wenn es unbedingt sein muss, kannst du ja vor dem eigentlichen Auslesen der Daten einfach mal das Überflüssige "ins Leere" auslesen. Dazu musst du wissen, wieviele Strings überflüsig sind. Wenn es nur einer ist, sieht es so aus:
fid = fopen(...);
fscanf(fid,'%g',1);
daten = fscanf(fid,'%g %g %g %g %g',[5 inf])';
fclose(fid);
Aber du musst beim ersten Lesen immer die richtige Anzahl überflüssiger Strings angeben, sonst geht es in die Hose!
Gruß
Martin
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 23:55 Mi 22.11.2006 | Autor: | CzumA |
Wow,
danke für diese Blitzantwort! Werde es gleich mal testen, aber wird sicher funtkionieren so.. eleganter kann ich es mir im moment auch nicht vorstellen..
Was mir gerade noch durch den Kopf geht.. Ich lese ja 5 Spalten ein... es wird alles in "Daten" geschrieben.. mit Daten(1) kann ich z.B. den ersten Wert der ersten Spalte abrufen.. mit Daten(2) den zweiten Wert der ersten Spalte usw.. ist er am Ende der ersten Spalte, springt er ja direkt in die zweite..
Kann ich "ihm" nun irgendwie sagen, dass er (z.B. für eine Schleife) nur die Daten der ersten Spalte checken soll ? Oder muss ich immer alle durchlaufen ? Ich weiss in diesem Fall zwar, wieviel Zeilen ich pro Spalte habe und könnte es angeben, aber krieg ich eine andere Tabelle geht diese Variante logischerweise schief..
Nochmals DANKE! :)
MfG
|
|
|
|
|
Hallo,
das mit den Zeilen und Spalten ist kein Problem.
Man kann daten als Vektor ansprechen. Dann durchläuft man alle Elemente nacheinander.
Man kann daten aber auch als Matrix ansprechen (so war es ja bei der Tabelle gedacht). Dann erhält man mit daten(234, 3) das Element in der 3. Spalte und 234 Zeile.
Weitere Möglichkeiten zum Umgang mit Matrizen:
daten(:,1) -> gesamte erste Spalte
daten(5:end,2) -> alle Elemente der zweiten Spalte bis auf die ersten vier
daten(1:end-4,3) -> alle Elemente der dritten Spalte bis auf die letzten vier
daten(1:4:end,4) -> jedes vierte Element der vierten Spalte
daten(find(daten(:,5)>4),5) -> jedes Element der fünften Spalte, das größer ist als vier
Na ja, diese Tipps nur so am Rande. Sie können einem so manche for-Schleife ersparen.
Gruß
Martin
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 00:37 Do 23.11.2006 | Autor: | CzumA |
Dieses Forum wird seinem Prinzip mehr als gerecht!! Und nochmals ein DICKES DANKE! Das erleichtert mein Vorhaben um einiges.. (war gerade schon am for-Schleife basteln, *g*)
Vorerst nerv ich dich nicht mehr, werde mich die nächsten Tage etwas intensiver mit meiner weiteren Problematik auseinandersetzen und dann mal schauen, wie weit ich komme :)
MfG
|
|
|
|