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

Iterative Vergleiche mit if und while noch beschleunigen

 

TasseKaffee
Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 03.03.21
Wohnort: ---
Version: R2020b
     Beitrag Verfasst am: 03.03.2021, 14:35     Titel: Iterative Vergleiche mit if und while noch beschleunigen
  Antworten mit Zitat      
Hallo zusammen,

als Anfänger in MatLab habe ich hier eine Frage zur Laufoptimierung eines MatLab-Codes.
Gegeben ist eine Liste/Zeitreihe mit ca. 35.000 Messwerten über ein ganzes Jahr mit Datum und Uhrzeit.

Anhand des Datums und der Zeit soll nun gefiltert werden, ob die jeweiligen Zeilen ein Wochentag sind und, ob sie zusätzlich in ein bestimmtes Monats- und Zeitfenster fallen. Falls die drei Bedingungen erfüllt sind, soll der Messwert der Zeile in eine neue Spalte geschrieben werden.

Realisiert habe ich es erstmal iterativ mit while und if Schleifen, das ganze dauert ca. 12 Sekunden.

Lässt sich der Ablauf noch verschlanken und beschleunigen?

Code:

%In Spalte 1 der Liste steht das Datum (datetime).
%In Spalte 2 steht die Uhrzeit (excel-Format).
%In Spalte 3 stehen die Messwerte.

nData=size(Liste,1);  %Der Zähler nData wird auf die Menge der Messwerte gesetzt.
n=1;

Frue1von=ZeitfensterEingabe{1,2}+ZeitfensterEingabe{1,3}/60;
Frue1bis=ZeitfensterEingabe{1,4}+ZeitfensterEingabe{1,5}/60;
%..
%..
%... Für jede Jahreszeit werden hier die Zeitfenster eingegeben.

Liste{:,4}=month(Liste{:,1});
Liste{:,5}=day(Liste{:,1},"dayofweek");
Liste{:,6}=Liste{:,2}*24;


while n<nData  %Für jede Zeile/Messwert, vergleiche...
   
    if Liste{n,5}>=2 && Liste{n,5}<=6 %Wochentag ? 1=Sonntag Samstag=7 Mo-Fr=2-6
       
        if Liste{n,4}>2 && Liste{n,4}<6 %Frühling ?
            if Liste{n,6}>=Frue1von && Liste{n,6}<=Frue1bis %Zeitfenster1 ?
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Frue2von && Liste{n,6}<=Frue2bis %Zeitfenster2 ?
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Frue3von && Liste{n,6}<=Frue3bis %Zeitfenster3 ?
                Liste{n,7}=Liste{n,3};
            end
        elseif  Liste{n,4}>5 && Liste{n,4}<9 %Sommer ?
            if Liste{n,6}>=Sommer1von && Liste{n,6}<=Sommer1bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Sommer2von && Liste{n,6}<=Sommer2bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Sommer3von && Liste{n,6}<=Sommer3bis
                Liste{n,7}=Liste{n,3};
            end
        elseif     Liste{n,4}>8 && Liste{n,4}<12 %Herbst ?
            if Liste{n,6}>=Herbst1von && Liste{n,6}<=Herbst1bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Herbst2von && Liste{n,6}<=Herbst2bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Herbst3von && Liste{n,6}<=Herbst3bis
                Liste{n,7}=Liste{n,3};
            end
        elseif Liste{n,4}>11 || Liste{n,4}<3 %Winter ?
            if Liste{n,6}>=Winter1von && Liste{n,6}<=Winter1bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Winter2von && Liste{n,6}<=Winter2bis
                Liste{n,7}=Liste{n,3};
            elseif Liste{n,6}>=Winter3von && Liste{n,6}<=Winter3bis
                Liste{n,7}=Liste{n,3};
            end
        end
    end
    n=n+1;
end
Private Nachricht senden Benutzer-Profile anzeigen


Mmmartina
Forum-Meister

Forum-Meister


Beiträge: 745
Anmeldedatum: 30.10.12
Wohnort: hier
Version: R2020a
     Beitrag Verfasst am: 05.03.2021, 14:57     Titel:
  Antworten mit Zitat      
Normalerweise kann Matlab sehr gut und schnell mit Matritzen arbeiten.
D.h. direkte Indexierung einer MAtrix könnte schneller sein.

Somit würde ich die Cellmatrix in eine num. Matrix umwandeln und direkt mit den Indexen arbeiten.
_________________

LG
Martina

"Wenn wir bedenken, daß wir alle verrückt sind, ist das Leben erklärt." (Mark Twain))
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.446
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 05.03.2021, 23:58     Titel:
  Antworten mit Zitat      
Hallo,

mich verwundert an dem Code, dass doch letztlich für alle erdenklichen Bedingungen immer das gleiche gemacht wird:
Code:
Liste{n,7}=Liste{n,3};

Auch die Logik für die Bestimmung der Jahreszeit wundert mich. Wozu braucht man da drei verschiedene Zeitfenster?

Logische Indizierung / Zuweisung könnte das while/if ersetzen. Dazu wäre gut zu wissen, ob Intervalle wie [Frue1von, Frue1bis] und [Frue2von, Frue2bis] überlappend sind.

Ein reproduzierbares Beispiel ist generell hilfreich.
Zitat:
%In Spalte 2 steht die Uhrzeit (excel-Format).

Ich wüsste nicht, dass es in Excel genau ein Format für die Uhrzeit gibt - und noch weniger, wie man damit rechnen sollte.

Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
TasseKaffee
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 03.03.21
Wohnort: ---
Version: R2020b
     Beitrag Verfasst am: 08.03.2021, 12:39     Titel:
  Antworten mit Zitat      
Hallo,

danke, Martina! Diesen Tipp habe ich am Freitag teilweise umgesetzt. Die Liste habe ich in eine Matrix umgewandelt:

Code:

mat = zeros(35136,6);  %Könnten auch einfach 4 Spalten sein.
for i=3:6    %3. bis 6. Spalte sind für die Berechnung wichtig.
    mat(:,i)=Liste{:,i};
end


Mmmartina hat Folgendes geschrieben:
Normalerweise kann Matlab sehr gut und schnell mit Matritzen arbeiten.
D.h. direkte Indexierung einer MAtrix könnte schneller sein.

Somit würde ich die Cellmatrix in eine num. Matrix umwandeln und direkt mit den Indexen arbeiten.


Den restlichen Code habe ich so gelassen, da ich noch nicht auf die Umsetzung der (logischen) Indizierung gekommen bin. Ich arbeite noch mit den If-Schleifen. Die Rechenzeit hat sich nur durch die Matrix von ca. 30 sek. auf 0,26 sek. reduziert.

Hallo Harald, dass nach jeder Bedingung die gleiche Anweisung steht, ist mir auch bewusst. Da habe ich noch keine Vereinfachung. Es sollen die Messwerte zu diesen Jahreszeiten und Uhrzeiten in die 7. Spalte geschrieben, also vom Rest gefiltert werden. Die Zeitfenster / Intervalle überlappen nicht.

Bei mir liegt die Uhrzeit im Format 0 Uhr=0 und 12 Uhr=0.5 aus Excel vor, welches in ein dezimales Format umgewandelt wird, 13:15 Uhr = 13.25.

Mich interessiert gerade die logische Indizierung, um die Schleifen zu ersetzen. Da werde ich mal weiterarbeiten.
Private Nachricht senden Benutzer-Profile anzeigen
 
TasseKaffee
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 03.03.21
Wohnort: ---
Version: R2020b
     Beitrag Verfasst am: 08.03.2021, 19:05     Titel:
  Antworten mit Zitat      
So, nach etwas Beschäftigung mit logischer Indizierung u.a. mit diesem Beitrag

https://www.gomatlab.de/logische-in.....immter-spalte-t34957.html

habe ich nun folgende Fragen:

1)Geht folgendes..? Mit der Indizierung Werte aus einer Spalte in eine andere Spalte der gleichen Zeile schreiben, wenn die Bedingung der Indizierung erfüllt ist?

Vorher:
Code:

mat(mat(:,5)>=2 & mat(:,5)<=6,7)=1
 


In Worten: In der 7. Spalte werden die Zeilen 1 gesetzt, wenn die Werte der Zeilen on 5. Spalte zwischen 2 und 6 liegt.

Kann man nun auch schreiben, dass statt einer 1 die Zeile gleich dem Wert einer anderen Spalte (z.b. Messwert) auf gleicher "Höhe" /Zeile gesetzt wird?

Etwa so:
Code:

mat(mat(:,5)>=2 & mat(:,5)<=6,7)=Wert aus Spalte 3 gleicher Zeile in Spalte 7 dieser Zeile schreiben
 


2) Kann man mithilfe einer passenden Zeitangabe die Zeitfenster vereinfacht in die Bedingung einbringen (etwa wie bei isbetween)?

Code:
mat(mat(:,6)<7.5 | mat(:,6)>12, 10)=0;
mat(mat(:,6)<17 | mat(:,6)>19.5, 10)=0;


In Worten: Setze alle Werte in Spalte 10 außerhalb von 7:30 Uhr und 12 Uhr (der Spalte 6 )auf 0 usw.

Ziemlich zurecht gebogen, da die zweite Codezeile die erste beeinträchtigt, folglich kann das nicht der richtige Ansatz sein.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.446
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 08.03.2021, 21:27     Titel:
  Antworten mit Zitat      
Hallo,

1)
Code:
mat(mat(:,5)>=2 & mat(:,5)<=6,7)=mat(mat(:,5)>=2 & mat(:,5)<=6,3);

oder übersichtlicher:
Code:
col5cond= mat(:,5)>=2 & mat(:,5)<=6;
mat(col5cond, 7) = mat(col5cond, 3);


2)
Ich vermute, du möchtest
Code:
mat((mat(:,6)<7.5 | mat(:,6)>12) & (mat(:,6)<17 | mat(:,6)>19.5), 10)=0;
 


Eine isbetween-Funktion kannst du dir im Zweifelsfall auch selbst schreiben:
Code:
function tf = istZwischen(x, a, b)
tf = (x >= a) & (x <= b);


Grüße,
Harald
_________________

1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
TasseKaffee
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 4
Anmeldedatum: 03.03.21
Wohnort: ---
Version: R2020b
     Beitrag Verfasst am: 09.03.2021, 16:27     Titel:
  Antworten mit Zitat      
Danke Harald,

das hat mir sehr weitergeholfen!

1) War mir eine gute Grundlage, um weiterzuentwickeln.

2) Hat genau gepasst. Eine isbetween-Funktion habe ich nicht gebraucht.

Viele Grüße
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 - 2024 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.