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

Zwei Matrizen mit unterschiedlichen NaN Werten ergaenzen

 

RatioTM
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 51
Anmeldedatum: 24.04.18
Wohnort: Genf
Version: ---
     Beitrag Verfasst am: 30.12.2018, 14:49     Titel: Zwei Matrizen mit unterschiedlichen NaN Werten ergaenzen
  Antworten mit Zitat      
Hallo,

ich habe zwei Zeitreihen (Foto angehaengt). Ich moechte fuer diese einen Mittelwert bilden, wobei ihr bei angehaengtem Foto sehen koennt, dass beide Zeitreihen an unterschiedlichen Stellen NaN Werte haben (das sieht beispielsweise so aus:)
a= [90 88 85 NaN NaN NaN 65 66 64 68 55 NaN 48 NaN 46]
b= [89 87 83 84 75 68 66 NaN NaN 67 53 49 47 45 46]
Die Zeitreihen ergaenzen sich jedoch wunderbar. Aus diesem Grund ware das Ziel eine Matrix c, die nichts anderes ist, als (a+b)/2, wobei NaN Werte durch die vorhandenen Werte von a bzw b aufgefuellt werden. Genau da ist jedoch das Problem. Was ich ich mir ueberlegt habe:
Ich bilde eine Matrix c nach obigem Prinzip und erhalte (nach bsp oben):
c= [89.5 87.5 84 NaN NaN NaN NaN NaN 65.5 52 NaN 46]
Anschliessend ergaenze ich c indem ich die NaN Werte durch vorhandene Messwerte von a oder b auffuelle. Doch genau da hapert es:
Werte mit 0 auffuellen mag funktionieren ueber
Code:
d=isnan(c);
c(d)=0;

jedoch will ich ja die passenden werte von a bzw b einfuegen.
Eine weitere Option waere, die matrix c von Anfang an ohne NaN Werte aufzubauen, etwa in einer Schleife:
Code:
for i=1:length(a)
c(:,i)=(a(:,i)+b(:,i))/2
if a(:,i) isnan
c(:,i)= (b(:,i)*2)/2
end
if b(:,i) isnan
c(:,i)=(a(:,i)*2)/2
end
end
 


Ich haenge jedoch bei beiden Ansaetzen fest. Kennt ihr eventuell leichtere Moeglichkeiten, die mich zum Ziel fuehren?

Vielen Dank fuer eure Hilfe und VG!

data.png
 Beschreibung:

Download
 Dateiname:  data.png
 Dateigröße:  48.65 KB
 Heruntergeladen:  275 mal
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.432
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.12.2018, 15:39     Titel:
  Antworten mit Zitat      
Hallo,

wie wäre dann
Code:
c = mean([a;b], 'omitnan')


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
 
RatioTM
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 51
Anmeldedatum: 24.04.18
Wohnort: Genf
Version: ---
     Beitrag Verfasst am: 30.12.2018, 16:23     Titel:
  Antworten mit Zitat      
Hallo Harald,

das wuerde den Zweck erfuellen, wenn ich einen allgemeinen Mittelwert fuer die gesamte Zeit suchen wuerde (zumindest wenn ich es ausprobiere). Jedoch moechte ich die NaN Werte durch die werte der matrix a bzw b ersetzen, um eine durchgehende Zeitreihe zu erhalten.

Eine weitere Frage, die sich mir stellt, ist folgende:

Ich wuerde die Zeitreihe gerne mitteln, sodas Schwankungen weniger stark hervorgehoben werden. Dafuer habe ich mir folgende function gemacht:
Code:
function C= averaging(n,a);

C= [];

C= arrayfun(@(i) mean(a(i:i+n-1)),1:n:length(a)-n+1)';

Das funktioniert auch ganz gut. Danach moechte ich den gemittelten Vektor jedoch wieder verlaengern, um auf die Laenge eines anderen Vektors zu kommen (die Zeitreihe soll also "gesmoothed" werden, sodass die Schwankungen geringer werden). Gibt es hier Ideen, wie ich vorgehen kann?
Ich habe in diesem Forum einen Beitrag von dir gefunden von 2014:
Code:
output(end+1:end+60) = output(end);

Das wuerde jedoch die Matrix einfach nur am letzten Wert um 60 Werte verlaengern. Ziel waere In meinem Fall allerdings, nach jedem einzelnen Wert den letzten Wert beispielsweise um den Wert 3 zu verlaengern.

Beispiel hier waere zu B zu kommen:
A= [7 9 3 6 5 10]
A= averaging(2,A)
--> A = [8 4.5 7.5]
...gesuchter Zwischenschritt....
-----> B= [8 8 8 4.5 4.5 4.5 7.5 7.5 7.5]

VG
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.432
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.12.2018, 17:48     Titel:
  Antworten mit Zitat      
Hallo,

wenn a und b Zeilenvektoren sind, dann bekommst du mit meinem Vorschlag eine Zeitreihe. Wenn du die NaN behalten willst, dann das 'omitnan' weglassen.

Ich verstehe nicht recht, was du erreichen möchtest. Z.B. wie in deinem Beispiel das drittletzte Element 52 zustande komm.

Für die andere Frage sollte repelem helfen.

Statt dem arrayfun-Ansatz kann man die Elemente auch mit reshape so umsortieren, dass die zu mittelnden Werte in Spalten stehen. Für große Matrizen dürfte das von der Performance her deutlich besser sein.

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
 
RatioTM
Themenstarter

Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 51
Anmeldedatum: 24.04.18
Wohnort: Genf
Version: ---
     Beitrag Verfasst am: 25.01.2019, 18:00     Titel:
  Antworten mit Zitat      
Hallo Harald,
entschuldige meine spaete Antwort und vielen Dank fuer die Ratschlaege!
Die 52 in meinem obigen Beispiel war nur ein grober Aufschrieb als Beispiel dessen, was ich erreichen wollte.

Ich habe obige Problemstellung (smoothing der Daten und ersetzen der NaN Werte) mit folgender function geloest:

Code:

function a= replaceNans (b)
%a== matrix b, were the NaN values are replaced by the last values of b
%before they went NaN


mask = ~isnan(b);
cumsums = cumsum(mask,1);
invalid_mask = cumsums==0;
cumsums(invalid_mask) = 1;

shifts = [0 cumsum(sum(mask(:,1:end-1),1))];

idx = bsxfun(@plus,cumsums, shifts);
nums = b(mask);
out = nums(idx);
out(invalid_mask)=nan;
a =out;

 


Anschliessend habe ich die nanfastsmooth funktion verwendet.

VG,

Ratio
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.