Verfasst am: 27.09.2010, 19:58
Titel: Datentrennung + Variablen mit Index
Hallo Zusammen,
ich sitze hier vor einem Berg von Messdaten. Es sind ca. 25 Variablen/Matrizen mit jeweils rund 680000 Messwerten. (1x680000)
Jede Variable beinhaltet die Daten von 20 gleichen Messungen, jedoch unterscheiden diese sich voneinander ein wenig. D.h. sowas in der Art wie ___1234___1345___3479___ ...
Problem 1 ist nun diese 20 Events voneinander zu trennen. Dazu habe ich mir ueberlegt die 'Nullen' zwischen den Events zu zaehlen.
Dies funktioniert soweit auch, benoetigt aber viel zu viel Zeit.
Besteht die Moeglichkeit die Daten ohne Schleife(n) voneinander zu trennen?
Ein weiteres Problem habe ich mit der Speicherung der selektierten Daten. Die Matrix G beinhaltet Daten die ich z.B. in G1 speichern moechte. Mir fehlt nun der Befehl um nun im zweiten Durchlauf G2 zu speichern...G3,G4...G20
-> Problem 2 mit 'XXXXXX' im Code markiert
Schon einmal vielen Dank!
Falls noch es nicht ganz verstaendlich ist, bitte nachfragen...
Edwin
Code:
% Code uebersichtshalber mit nur 3 Variablen:
%% Combine the Single-Matrices to one MATRIX
D=[A;B;C]
D1=D;
%%
%% Working with the MATRIX
%%
%% Examination of the whole MATRIX on values <0.2 % If it exists, set column zero
% running numbers:
q=1;
n=0;
m=1;
% Anzahl der Elemente der Matrix:
% Number of rows and columns of the MATRIX -> saved in the Variables [rows, columns]=size(D) % columns=length(A) % rows=3; tic while q<columns
VAR=D(1,q);
% q
n=0 if VAR<0.2
'Value < 0.2';
D(:,q)=zeros(1,rows);
A=D(1,:);
NumberofZeros=sum(A==0)
%% Counting the number of ZEROS if NumberofZeros >8
i
D(1,q-2)
D(1,q-1) if(D(q-4))==0 && (D(q-1))==0 % Save the left Matrix seperated (#1 of 20 Events)
G=D(:,[1:q])
XXXXXX
% Delete the rows from the MATRIX which are in G
D(:,[1:q]) = [] % Define the new number of rows and columns of the MATRIX -> saved in % the Variables [rows, columns]=size(D)
n=q
Verfasst am: 27.09.2010, 21:37
Titel: Re: Datentrennung + Variablen mit Index
Hallo Edwin,
Zitat:
D.h. sowas in der Art wie ___1234___1345___3479___ ...
Problem 1 ist nun diese 20 Events voneinander zu trennen. Dazu habe ich mir ueberlegt die 'Nullen' zwischen den Events zu zaehlen.
Was bedeutet ___1234___1345 ?
Was sind "Events"?
Was sind 'Nullen'?
Wo zählst Du in Deinem Code Nullen zwischen Events?
Zitat:
Ein weiteres Problem habe ich mit der Speicherung der selektierten Daten. Die Matrix G beinhaltet Daten die ich z.B. in G1 speichern moechte. Mir fehlt nun der Befehl um nun im zweiten Durchlauf G2 zu speichern...G3,G4...G20
Wird mir nicht klar. Ich find kein G1 in Deinem Code.
Zitat:
Code:
...
n=0% Schreibt ins Command Window => langsam! ...
'Value < 0.2'; % Macht gar nichts => löschen
...
% Weist einem Spalten Vektor eine Zeile - das sollte crashen:
D(:,q)=zeros(1,rows); % D(:, q) = 0 ist wohl schneller ...
NumberofZeros=sum(A==0)% Ausgabe unnötig!
...
i% Ausgabe unnötig!
D(1,q-2)% Ausgabe unnötig!
D(1,q-1)% Ausgabe unnötig! ...
G=D(:,[1:q])% Ausgabe unnötig, 1:q ist schneller als [1:q] ...
D(:,[1:q]) = []% Ausgabe unnötig, 1:q ist schneller als [1:q] ... [rows, columns]=size(D)% Ausgabe unnötig
n=q % Ausgabe unnötig ...
'Value > 0.2!'; % ??? end % q
q=q+1-n % Ausgabe unnötig
Ich vermute, das Program vertrödelt 50% der Zeit mit den Ausgaben ins Command-Window. Mir wird die Funktion vieler Zeilen nicht klar. Was bring z.B. " 'Value > 0.2!';" ???
Ja das mit dem ___1234___1345 sollte nur bildlich gemeint sein. In diesem Code sind nun die Matrizen A, B, C vorhanden.
Die Messdaten die ich vearbeiten muss sind mit A, B, C vergleichbar, jedoch um einiges laenger.
Alle Werte die in Matrix 'A' <0.2 sind, sollen zu Null gesetzt werden.
Eine Matrix (vgl A) ist aus 20 gleichen 'Events' aufgebaut, d.h. es wird innerhalb sagen wir 70s 20mal der gleiche Messablauf gestartet. Zwischen diesen 20 Messablaeufen sind kurze Pausen in denen der Wert ~0 erreicht wird. Deshalb 'Nullen zaehlen'. Diese Matrix soll nun in 20 separaten Matrizen gespeichert werden, welche jeweils 1 Messablauf beschreiben.
In der Zwischenzeit habe ich die Loesung fuer das Speichern von G als G1, G2...G20 gefunden. Es ist dieser "eval(['G' num2str(m) ' = G;'])" Befehl.
Die meisten Ausgaben waren fuer mich erstmal nur zum Ueberblick ob alles so funktioniert wie ich das moechte. Diese sind natuerlich ueberfluessig. Aber ich habe mir gedacht das die Schleifen mehr Zeit benoetigen als diese kleinen Ausgaben.
%% Example
A=[0.11.01.52.00.03.52.00.140.120.10.18754321.30.50.30.20.190.180.140.010.10.10.70.91.05.04.02.30.90.70.20.10.10.1];
B=[40507912301412124500.1200.50.60.70.910899090120141472230.20.20.10.81.52.55.056560.50.40.30.1];
C=[23890710200.087.07.58.58.94.50.20.10.10.30.15.89.69.33.63.76.51.22.00.40.30.20.10.1 .010.120.10.10.1];
%% Time-Definition
t=0:70/671965:70;
%% Combine the Single-Matrices to one MATRIX
D=[A;B;C]
D1=D;
%%
%% Working with the MATRIX
%%
%% Examination of the whole MATRIX on values <0.2 % If it exists, set column zero
% running numbers:
q=1;
n=0;
m=1;
% Anzahl der Elemente der Matrix:
% Number of rows and columns of the MATRIX -> saved in the Variables [rows, columns]=size(D)
tic while q<columns
VAR=D(1,q);
% q
n=0;
if VAR<0.2
D(:, q) = 0;
% D(:,q)=zeros(1,rows);
A=D(1,:);
NumberofZeros=sum(A==0);
%% Counting the number of ZEROS if NumberofZeros >=3
% Define the gaps between the single events if(D(q-2))==0 && (D(q-1))==0
% Save the left Matrix seperated (#1 of 20 Events)
G=D(:,[1:q]);
eval(['G' num2str(m) ' = G;'])
m=m+1 ;
% Delete the rows from the MATRIX which are saved in G
D(:,[1:q]) = [] % Define the new number of rows and columns of the MATRIX -> saved in % the Variables [rows, columns]=size(D)
n=q
In der Zwischenzeit habe ich die Loesung fuer das Speichern von G als G1, G2...G20 gefunden. Es ist dieser "eval(['G' num2str(m) ' = G;'])" Befehl.
Das ist eine dramatisch ineffiziente Methode Variablen zu speichern. Es wäre viel besser statt dessen eine Cell zu verwenden: GG{i} = G;
Falls Dich das interessiert, liess einfach mal in einigen anderen hundert Threads nach, in denen ich schon etwas dazu geschrieben habe -- ich gebe zu, ich muss für das forum ziemlich langweilig sein.
Zitat:
Die meisten Ausgaben waren fuer mich erstmal nur zum Ueberblick ob alles so funktioniert wie ich das moechte. Diese sind natuerlich ueberfluessig. Aber ich habe mir gedacht das die Schleifen mehr Zeit benoetigen als diese kleinen Ausgaben.
Deswegen sage ich es ja: Die Ausgabe ins Command-Window ist erschreckend langsam! Dazu wird eigens ein Java-Interpreter bemüht, der recht ineffizient versucht HREF-Strings herauszufiltern und die Scrollbalken upzudaten. Matlab 6.5 wurde sogar bis zu 10% schneller wenn man nach jeweils 8 Ausgabezeilen ein PAUSE(0.01) einlegte, damit Java die Chance bekam, seine voll-laufenden Buffer zu leeren. Offenbar klappte auch dort die Pre-allocation nicht.
Also: Weg mit unnötigen Ausgaben. Nutze zum Debuggen lieber den Debugger.
Die Zeile " 'Value > 0.2'; " bleibt mir immer noch ein Rätsel. KannSt Du bitte erjklären, was sie bewirken soll?
Wie gesagt ist in "D(:,[1:q]) = []" die eckige Klammerung um "1:q" überflüssig.
Ich würde generell niemals die Matrix D stück für Stück verkleinern, weil dabei jedesmal neuer Speicher allociert werden muss. Es wäre heftig viel schneller statt dessen nur die Indices zu bestimmen, an denen die Matrix verändert werden. Statt "1:q" wäre das dann "p:q" mit geeigneten p und q.
ist auf jedenfall hilfreich, mit diesem werde ich mich nochmal beschaeftigen.
Da ich mit Matlab noch nicht sehr vertraut bin, sagen mir die ganzen Funktionen und deren Hintergrundfunktionen noch nichts. Zum Thema anit-eval-Funktion habe ich einiges gefunden, jedoch habe ich noch keinen Ansatz gefunden wie ich die Cell-Funktion bei mir verwenden koennte.
Wuerdest du mir bitte nochmals deinen Ansatz der cell-Funktion erklaeren? Vielen Dank!
Mein 'neues' Programm (siehe unten) funktioniert im Prinzip so wie ich es haben wollte. Jedoch benoetigt es ca eine halbe Stunde bis es fertig ist. Zudem verwende ich massig diese 'eval'-Funktion
Das mit dem " 'Value > 0.2'; " ist voellig sinnlos gewesen - reiner Zeitfresser. Ist noch ein Mitbringsel aus der ersten if-Funktionen eines Tutorials
Zitat:
Ich würde generell niemals die Matrix D stück für Stück verkleinern, weil dabei jedesmal neuer Speicher allociert werden muss. Es wäre heftig viel schneller statt dessen nur die Indices zu bestimmen, an denen die Matrix verändert werden. Statt "1:q" wäre das dann "p:q" mit geeigneten p und q.
Hier komme ich nicht mehr ganz mit. Meine Matrix D verkleinere damit, in dem ich die (linken) Werte bis zu einer gewissen Anzahl an Nullen in der ersten Zeile zaehle und dann in Matrix G speichere. Diese Werte die damit in G gespeichert sind loesche ich aus D. Damit wird diese Matrix D kleiner, soweit komme ich mit.
Aber was meinst du mit allocieren des Speichers bzw. wie bestimme ich p? Habe ich mit diesem Vorhaben spaeter immer noch die Gro=e von D wie anfangs, jedoch mit Nullen vollbesetzt?
Ziel ist es immer noch aus der gro=en Matrix D 20 kleine Matrizen G1...G20 zu machen.
Eine neue Frage hat sich mir beim Laden der Variablen aus der *.mat-File gestellt. In meinem Code lade ich jede Variable einzeln ins Script-File. Besteht die Moeglichkeit dies so zu programmieren, dass Matlab alle Variablen aus dem Workspace benutzt und mir damit dann die Matrix D erzeugt?
Das bringt mir allerdings nur dann einen Vorteil, wenn ich anschlie=end beim Speichern ebenfalls eine Logik verwenden kann, welche mir die neu entstandenen Variablen (vgl eval-funktionen) in einem anderen *.mat-File speichert. Dabei sollten die Variablen-Namen jeweils den Ausgangsvariablen aehneln bzw den Zusatz der Laufzahl 'm' erhalten
%% Import the raw-data from file...
inputPath = uigetdir(); % search file cd(inputPath); % input path of file
dir_str=dir('*.mat'); % show me the variables from file 9.mat in workspace % file_names = {dir_str.name}; load9.mat% load *.mat-file, which created with UNIVW
%%
%% Working with the MATRIX
%%
%% Examination of the whole MATRIX on values <0.2 % If it exists, set column zero
% running numbers:
q=1; % count the columns (sample rate)
n=0; % need to delete the separated data from big MATRIX
m=1; % count the events in every file (#1,#2,... of 20) zeros=10000; %9600; % cut after # of zeros
%Number of zeros to cut the matrix: 1s/.104ms (Pause-Time/Sample-Rate)
% Number of rows and columns of the MATRIX -> saved in the Variables [rows, columns]=size(D);
COL=columns;
% columns=length(A); % rows=3;
% Delete the rows from the MATRIX which are saved in G
D(:,1:q) = [];
% Define the new number of rows and columns of the MATRIX -> saved in % the Variables [rows, columns]=size(D);
n=q;
Besteht die Moeglichkeit dies so zu programmieren, dass Matlab alle Variablen aus dem Workspace benutzt und mir damit dann die Matrix D erzeugt?
Das bringt mir allerdings nur dann einen Vorteil, wenn ich anschlie=end beim Speichern ebenfalls eine Logik verwenden kann, welche mir die neu entstandenen Variablen (vgl eval-funktionen) in einem anderen *.mat-File speichert. Dabei sollten die Variablen-Namen jeweils den Ausgangsvariablen aehneln bzw den Zusatz der Laufzahl 'm' erhalten
Mache das nicht. Haufenweise Variablen dynamisch zu erzeugen bringt immer Probleme, wenn Du später wieder darauf zugreifen möchtest. Ausserdem macht genau diese Method das Programm ja so langsam. Variablen-Namen mit Indices zu mischen ist ein Programmierstil, von dem ich (mal wieder) deutlich abraten würde.
Ich steige von Version zu Version weniger durch Dein Programm durch. Jetzt verwendest Du zusätzlich den Variablen-Namen "zeros", der eigentlich eine Matlab-Funktion ist. Bekommst Du da keine Warnung von Matlab? Dann speicherst Du alle Variablen im MAT-File. Wenn Du dieses File dann später mit LOAD ohne Output lädst, wirst Du auch in dort die Funtion ZEROS nicht mehr benutzen können.
Du schreibst von "columns", wenn Du die 2. Dimension meinst. In Matlab heisst das "rows".
Der Wust an EVALs ist gruselig (wie immer: meiner persönlichen Meinung nach). Ist es nicht schwierig zuerst kompliziert viele Variablen zu erzeugen, um dann hinter Schwierigkeiten zu haben, wieder darauf zugreifen zu können?!
Du hast sehr viele Zeilen im Code stehen, die eigentlich nur das Lesen erschweren: "clear all; clear all; clc"? Kommentare sind wertvoll wie Gold. Aber das Lesen hier im Forum wird durch:
%% Zeit-Definition
% Time-Definition
% t=0:70/671965:70;
nur blockiert. Es wäre einfacher, wenn Du hier nur ganz entrümpelten Code postest.
Zu dem Speicher-Allocation-Problem:
Wann immer Du eine neue Matrix erstellst, muss dafür Speicherplatz im RAM reserviert werden. Wenn Du also ein paar Zeilen in eine Matrix löschst. Bei großen Matrizen wird dies zum laufzeitbegrenzenden Faktor. Effizienter ist es einen Index-Vektor zu benutzen um auf Teile der Matrix zuzugreifen, die Original-Matrix aber unangetastet zu lassen.
Versuche es einfach mal. Lernen kann man ja am besten über's Probieren.
ist es moeglich mit MATLAB bzw. mit dem find-Befehl z.B. einen Bereich in einer Matrix anzuzeigen welcher gleiche Wert beinhaltet?
Also z.B.
B=[40 50 0 0 79 12 30 14 16 0 0 0 0 0 0 0 0 56 5 4 3 1];
Nun moechte ich haben, dass bei vorhandenen 8 Nullen mir angezeigt wird wo diese sich befinden. Also wo befindet sich der Anfang (B(1,10)) oder wo befindet sich das Ende von dem Paket von Nullen.
die Frage ist nicht klar genug. Suchst Du speziell nach 8 Nullen? Dann wäre FINDSTR geeignet.
Suchst Du nach den Stellen, an denen sich der Wert ändert? Dann versuche es mit FIND(DIFF(B)).
Suchst Du etwas anderes? Dann schreibe es nochmal genauer, bitte.
Also ich habe Daten von einem Pruefstand (4.5Mio Messwerte). Werte die kleiner als 0,2 sind setze ich zu Null.
Wenn jetzt 8000 Nullen nacheinander (0 0 0 0 0...) auftreten moechte ich wissen wo diese sind. Also ich suche entweder Anfang oder Ende dieser Nullen.
Ich habe naemlich an dieser Stelle vor diese Messwertereihe aufzutrennen und separat zu speichern.
soweit ganz einfach. Nun moechte ich die Matrix X genau dann auftrennen, wenn genau 4 Nullen nacheinander auftreten. Dabei sollen die Werte wie folgt gespeichert werden:
also hier folgen 5; 6; 7; 8; aufeinander und beschreiben vier Nullen. Genauso wie 23; 24; 25; 26; (dabei soll uebersichtshalber genau in der Mitte getrennt werden)
Meine Idee zur Loesung steht, aber mir fehlen die Befehle fuer die Ausfuehrung...
% Suche nach 4 Nullen:
Index4_0 = findstr(X, zeros(1, 4));
% Indices zum Splitten:
Split = Index4_0 + 2;
if Split(1) == 3% X startet mit 4 Nullen
Split = [Split, length(X) + 1];
else
Split = [1, Split, length(X) + 1];
end
C = cell(1, length(Split) - 1);
for iC = 1:length(Split) - 1
C{iC} = X(Split(iC):Split(iC+1)-1);
end
Darin kann man dann mit FIND (oder meistens schneller mit FINDSTR) nach den +1 und -1 Werten suchen: +1 ist der Übergang von Null->Nicht-Null, -1 umgekehrt.
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.