WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

textscan sehr grosser Dateien

 

KnutE51
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 17.12.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.12.2012, 16:00     Titel: textscan sehr grosser Dateien
  Antworten mit Zitat      
Bislang konnte ich mit

Code:


zeilenweise alle nötigen Infos einlesen. Nun habe ich eine Datei mit über 2 Mio Zeilen im txt Format. Nach der "alten" Methode sind hier mehrere Stunden rechenzeit nötig.

Mit

Code:

textscan(datFile, ' %s','delimiter','\n');
 


stehen die Daten mit 2 Mio Zeilen in 20 sec. schon mal im Speicher. Nun suche ich aber bestimmte Zeilen: mehrere hunderttausend haben dieses Format

Code:

$<--1--|<---2--|<---3--|<---4-- |<---5-- |<---6-- |
GRID              5           377.2055  -752.1-64.3679
GRID       30525           343.6035  -750.6   -5.6498
GRID       30526           428.3564-584.467    -8.468
GRID       30527             420.674-584.465-7.90609
 


(Hier mal als Code dargestellt, damit man das Format erkennen kann)

Wenn ich nun hier wieder mit if, oder switch, case Schleifen arbeite, dauert das wieder mehrere Stunden Rechenzeit.

Mit

Code:

row_GRID    = strncmp(FILE_IMPORTED{1,1}(:),'GRID',4);
Find_Grid     = find(row_GRID(:)==1);
GRID_Lines  = FILE_IMPORTED{1,1}(Find_Grid);
 


finde ich in unter 1 sec die Zeilen, die ich suche. Dann wird es aber schwierig dabei das Format herauszulesen, Block2, Block4, Block5 Block6, herauskommen sollte bei den vier Beispielzeilen

Block2 = [ 5 30525 30526 30527]
Block4 = [ 377.2055 343.6035 428.3564 420.674]
Block5 = [ -752.1 -750.6 -584.467 -584.465]
Block6 = [-64.3679 -5.6498 -8.468 -7.90609]

Gerade das halbwegs variable Format der Leerzeichen und Vorzeichen in Block 4,5 und 6 macht die Sache unübersichtlich. Die Blöcke haben aber alle ein 8er Format, d.h. Spalte
Block1= 1-8
Block2= 9-16
Block3=17-24
Block4=25-32
...
...

Hat jemand gute Ideen?
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 17.12.2012, 18:12     Titel: Re: textscan sehr grosser Dateien
  Antworten mit Zitat      
Hallo KnutE51,

20 Sekunden ist eine ganz schön lange Zeit für gerade mal 64MB an Daten. Vermute aber, dass dies auch nicht schneller ist als TEXTSCAN:
Code:
Data = fileread(FileName);
CStr = regexp(Data, '\n', 'split');

Aber im folgenden kann man etwas verschlanken, was aber bei weniger als einer Sekunde Laufzeit kaum auffallen wird:
Code:
C = FILE_IMPORTET{1};
row_GRID    = strncmp(C, 'GRID', 4);
% Find_Grid     = find(row_GRID);  % ==1 und (:) überflüssig
% Aber logical indexing ist noch besser:
GRID_Lines  = C(row_Grid);

Eigentlich beschränkt sich Deine Frage also auf: Wie konvertiert man folgenden Cell-String in diesen Vektor:
Code:

CStr = {'GRID              5           377.2055  -752.1-64.3679', ...
             'GRID       30525           343.6035  -750.6   -5.6498'};
Value = [ 5, 377.2055, -752.1, -64.3679; ...
             30525, 343.6035, -750.6, -5.6498];

Richtig?

Das sollte eigentlich mit SSCANF gehen, nachdem man die Strings zusammengefügt hat, aber ich kann es gerade nicht testen. Ich schaue wohl heute abend noch mal rein.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 17.12.2012, 23:55     Titel: Re: textscan sehr grosser Dateien
  Antworten mit Zitat      
Hallo KnutE51,

Ich habe es nun nochmal probiert und bin leider gescheitert.
Ich kann das so spezifizierte Format nicht nachvollziehen:
Code:
$<--1--|<---2--|<---3--|<---4-- |<---5-- |<---6-- |
GRID              5           377.2055  -752.1-64.3679
GRID       30525           343.6035  -750.6   -5.6498
GRID       30526           428.3564-584.467    -8.468
GRID       30527             420.674-584.465-7.90609

Dies scheint nicht der Erklärung mit der festen Breite von 8 Zeichen pro Block übereinzustimmen. Die Zeilen haben aber unterschiedliche Breiten.
Der dritte Block enthält gar keine Zahlen, sondern nur Leerzeichen?

Kannst Du bitte einen Testdaten-File posten? Ich vermute 100 Zeilen sollten reichen.

Etwas wie das Folgende kann dann die Daten extrahieren:
Code:
Str = sprintf('%s*', CStr{:});
Value = sscanf(Str, 'GRID%8g%8g%8g%8g*', [4,inf])

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
KnutE51
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 17.12.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 10:24     Titel:
  Antworten mit Zitat      
Hallo Jan,

danke für die Infos. Du hast absolut Recht mit "Eigentlich beschränkt sich Deine Frage also auf: Wie konvertiert man folgenden Cell-String in diesen Vektor"

Genau so sieht es aus. Ergänzend dazu kann man schreiben "Eigentlich beschränkt sich Deine Frage also auf: Wie konvertiert man folgenden Cell-String in diesen Vektor ohne die Verwendung von while, switch, oder for Schleifen..."

Funktionieren tut ja folgendes

Code:


run         = 1;

tic

while ( run == 1)

    % read line
    line = fgetl( datFile);
    % cut spaces
    line = deblank( line);
    % get commands and data
    [ comm, data] = strtok(line);    

   
    switch comm
   
         case 'GRID'
             
             node_id    = str2num(line( 9:16));
             koord_x    = str2num(line(25:32));
             koord_y    = str2num(line(33:40));
             koord_z    = str2num(line(41:48));
             xnodes( node_id, 1 ) = koord_x;    
             xnodes( node_id, 2 ) = koord_y;    
             xnodes( node_id, 3 ) = koord_z;    
                     
    end
 
    % Pruefung ob End of File
    eofstat = feof(datFile);
    if eofstat == 1
        run = 0;
    end
   
end
toc
 


tic toc zeigt bei bei einem 1 MB File dann so ca. 2 min an. Bei einem 100 MB File habe ich nach 20 Stunden abgebrochen...
Private Nachricht senden Benutzer-Profile anzeigen
 
KnutE51
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 17.12.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 10:26     Titel:
  Antworten mit Zitat      
Hmm, jetzt habe ich eigentlich gedacht, ich habe eine Beispieldatei angehängt... sieht man die irgendwo?

Gruß
Private Nachricht senden Benutzer-Profile anzeigen
 
KnutE51
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 17.12.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 12:27     Titel:
  Antworten mit Zitat      
Hallo Jan,

mit

Code:

Str = sprintf('%s*', CStr{:});
Value = sscanf(Str, 'GRID%8g%8g%8g%8g*', [4,inf])
 



funktioniert das im Ansatz ganz gut, allerdings wird nur der erste GRID in Value geschrieben. Liegt das daran, das in Str alles in EINEm String sind?

Gruß
Private Nachricht senden Benutzer-Profile anzeigen
 
KnutE51
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 17.12.12
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.12.2012, 13:17     Titel:
  Antworten mit Zitat      
So, jetzt habe ich die Lösung:

Code:

tic
FILE_IMPORTED   = textscan(datFile, ' %s','delimiter','\n');
toc

tic
row_GRID        = strncmp(FILE_IMPORTED{1,1}(:),'GRID',4);
toc

tic
GRID_Lines_Cell = FILE_IMPORTED{1,1}(row_GRID);
toc

tic
GRID_Lines_Str  = char(GRID_Lines_Cell);
toc

tic
node_id    = str2num(GRID_Lines_Str(:,9:16));
koord_x    = str2num(GRID_Lines_Str(:,25:32));
koord_y    = str2num(GRID_Lines_Str(:,33:40));
koord_z    = str2num(GRID_Lines_Str(:,41:48));
xnodes( node_id, 1 ) = koord_x;    
xnodes( node_id, 2 ) = koord_y;    
xnodes( node_id, 3 ) = koord_z;
toc
 


Rechenzeit beträgt 5sec, 0sec, 0sec,1sec,75 sec.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.