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

Werte eines Vektors "glätten"

 

VollesBrot
Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 16.10.2015, 10:48     Titel: Werte eines Vektors "glätten"
  Antworten mit Zitat      
Hallo Leute,

ich bin noch blutiger Anfänger was Matlab bzw. Programmierung betrifft. Zurzeit stehe ich vor folgendem Problem, welches für den normalen Anwender wohl eher kein Problem darstellen sollte.

Problemstellung:
Ich lese aus einer Excel Datei eine Spalte ein. In dieser sind Höhenangaben zu finden. Das funktioniert auch soweit. Ich erhalte also einen Vektor. Er sieht zum Beispiel so aus:

100
100
100
100
101
101
101
101
101
102
102
102
101
101
101
102
102
102

Die Werte werden also größer und auch wieder kleiner. Jetzt würde ich gerne aus diesem Vektor einen neuen bilden, welcher den sprunghaften Auf- und Abstieg „glättet“.
z.B. die Änderung von 100 auf 101 sollte so aussehen, dass die Anzahl der „100er“-Werte gezählt wird und dann die Differenz von 100 und 101 (also 1 =)) auf die vorhergehenden „100er“ Werte verteilt wird.
Das Endresultat sollte also wie folgt aussehen:

100
100,25
100,5
100,75
101
101,2
101,4
101,6
101,8
102
101,66
101,33
101
101,33
101,66
102
102
102
Leider stehe ich wirklich sehr planlos da……hoffe ihr könnt mir weiterhelfen.

Grüße
Vollesbrot
Private Nachricht senden Benutzer-Profile anzeigen


Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 16.10.2015, 15:13     Titel:
  Antworten mit Zitat      
hmm ich könnte mir vorstellen mit diff und find erstmal die stellen zu suchen wo sich was ändert. und dann zwischen diesen stellen zu interpolieren. vielleicht würde auch ein moving average filter zu einem ergebniss führen das dir gefällt.
_________________

richtig Fragen
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: 16.10.2015, 15:23     Titel:
  Antworten mit Zitat      
Schau dir mal die Befehle DIFF und FIND in der Hilfe an, damit solltest du weiter kommen. Alternativ könntest du schauen, ob die Mittelwertfilter bzw. Fensterfunktionen weiterhelfen. (https://de.wikipedia.org/wiki/Gleitender_Mittelwert, https://de.wikipedia.org/wiki/Fensterfunktion)

So, und ich mache zu viele Fenster auf, bevor ich beantworte - Winkow hat schon das selber geschrieben, wie ich.
_________________

LG
Martina

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 19.10.2015, 10:57     Titel:
  Antworten mit Zitat      
also mit diff und find bin ich nicht so zurecht gekommen. Ich habe es also mal wie folgt probiert. Die ersten Werte schreibt er mir auch korrekt doch dann geht es nicht mehr weiter.

Code:

vektoralt = [100; 100; 100; 100; 101; 101; 101; 101; 101; 102; 102; 102; 101; 101; 101; 102; 102; 102];

vAlt = vektoralt;
value = vAlt(1,1);
counter = 0;

ende = length(vAlt);

for i = 1:ende
    if vAlt(i,1) == value
        counter = counter + 1;
    end
   
    if vAlt(i,1) ~= value
        difference = vAlt(i,1) - vAlt(i-1,1);
        steps = difference / counter;
       
        for j = i-counter:counter
            vNew(j,1) = value + (j-1) * steps;
        end
       
        value = vAlt(i,1);
        counter = 0;
    end
end

 


Die Ausgabe für vNew ist dann

vNew = [100; 100,25; 100,5; 100,75]
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 19.10.2015, 14:40     Titel:
  Antworten mit Zitat      
Hallo,

eine Möglichkeit wäre Mittelwertfilter:

Code:
N = 3; % Fenstergröße
y = filter(ones(1,N)/N, 1, x);
y(1:N-1) = cumsum(x(1:N-1)) ./ (1:N-1)'; % Beheben des "Rampen-Beginns"


Grüße,
Harald
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: 19.10.2015, 16:32     Titel:
  Antworten mit Zitat      
Hallo VollesBrot,

Mit der Funktion RunLength aus http://www.mathworks.com/matlabcent.....eexchange/41813-runlength:
Code:
v = [100; 100; 100; 100; 101; 101; 101; 101; 101; 102; 102; 102; 101; 101; 101; 102; 102; 102];
[B, N, BI] = RunLength(v);
d   = [diff(B) ./ N(1:length(N)-1), 0];
add = RunLength(d, N);
add(BI) = 0;
v_new = v + add;

Ich kann das zur Zeit nicht testen. Falls Du keine MEX-files kompilieren möchtest, da man dazu auch einen Compiler installieren muss, verwende "RunLength_M" statt "RunLength".

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 20.10.2015, 10:23     Titel:
  Antworten mit Zitat      
Schon mal danke für den super Hinweis. Das geht nun schon mal in eine gute Richtung.
Es gab noch 2 Fehler bei den "matrix dimensions" in Line 3 und 6. Habe es nun ergänzt. Es sieht also nun so aus:

Code:
v = [100; 100; 100; 100; 101; 101; 101; 101; 101; 102; 102; 102; 101; 101; 101; 102; 102; 102];
[B, N, BI] = RunLength(v);
d   = [diff(B') ./ N(1:length(N)-1), 0];
add = RunLength(d, N);
add(BI) = 0;
v_new = v + add';



Die Ausgabe sieht nun so aus:

100
100,25
100,25
100,25
101
101,2
101,2
101,2
101,2
102
101,66
101,66
101
101,33
101,33
102
102
102

Ich muss jetzt also noch hinbekommen, dass "add" fortlaufend addiert bzw subtrahiert wird.
Aber das Ziel ist nun in Sicht Very Happy
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: 20.10.2015, 14:31     Titel:
  Antworten mit Zitat      
Hallo VollesBrot,

Ah, stimmt.
Leider wird genau dieser Punkt nicht einfach, da die N=1 Elemente eine besondere Behandlung brauchen. Mit ein paar Zeilen bekomme ich das nicht hin. Aber ich denke weiter drüber nach.

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 20.10.2015, 15:23     Titel:
  Antworten mit Zitat      
Über weitere Hilfe wäre ich sehr dankbar.
Bin bisher selbst noch nicht drauf gekommen.
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: 20.10.2015, 16:21     Titel:
  Antworten mit Zitat      
Hallo VollesBrot,

Mit einer Schleife geht das schon mal:
Code:
% Anfang wie von Dir oben gepostet. Dann:
% Statt: v_new = v + add';

v_new = zeros(size(v));
accum = 0;
for k = 1:numel(v)
  if add(k) == 0
    accum = 0;
  else
    accum = accum + add(k);
  end
  v_new(k) = v(k) + accum;
end

Vielleicht ist dies schneller:
Code:
accum = 0;
for k = 1:numel(v)
  accum    = (accum + add(k)) * (add(k) ~= 0);
  v_new(k) = v(k) + accum;
end

Wenn es nicht um Echtzeit-Anwendungen oder Milliarden von Zahlen geht, könnte das schnell genug sein.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 20.10.2015, 18:14     Titel:
  Antworten mit Zitat      
Hallo,

falls es das gewünschte Ergebnis liefert, scheint mir mein Vorschlag von 19.10., 14:40 deutlich einfacher zu sein.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
VollesBrot
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 21.10.2015, 10:14     Titel:
  Antworten mit Zitat      
Da es sich um keine Echtzeit-Anwendung handelt sondern meistens um Vektoren mit 60.000 - 70.000 Einträgen ist die Berechnungszeit mehr als ausreichend.

Nach den ersten Tests kann ich sagen, dass alles so funktioniert wie ich es mir vorgestellt habe.

Ein großer Dank an Jan und auch an Harald für die Anregungen und Lösungen. Very Happy
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: 21.10.2015, 11:08     Titel:
  Antworten mit Zitat      
Hallo Harald,

Zitat:
falls es das gewünschte Ergebnis liefert, scheint mir mein Vorschlag von 19.10., 14:40 deutlich einfacher zu sein.

Deutlich einfacher ist es, aber es werden nur Rampen der Länge N erzeugt. So weit ich es verstanden habe, sollen die Rampen aber für jede einzelne Phase mit gleichem Wert individuelle Längen haben.

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

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 16.10.15
Wohnort: ---
Version: R2014a
     Beitrag Verfasst am: 21.10.2015, 11:14     Titel:
  Antworten mit Zitat      
Richtig, die Rampen können sehr unterschiedliche Längen aufweisen. Daher hat sich das mit der festen Fenstergröße nicht angeboten.

Das hätte ich vielleicht etwas deutlicher formulieren müssen.
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.