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

NaN-Werte in einer Matrix durch gültige Nachbarwerte ersetz

 

Jonas_Student

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.10.2014, 18:45     Titel: NaN-Werte in einer Matrix durch gültige Nachbarwerte ersetz
  Antworten mit Zitat      
Hallo,

zunächst vielen Dank für dieses Forum. Ich habe mich in den letzten Wochen angefangen in Matlab einzuarbeiten und das fällt dank der vielen Beiträge hier sehr viel leichter !

Zum Problem:
Ich habe eine Matrix mit 5x5 Werten vorliegen. Teilweise sind NaN-Werte aufgrund von Messfehlern eingetragen.

[code]
A_start=[nan nan nan 4 5; nan nan 3 4 5; nan 2 3 4 5; 1 2 3 4 5; 1 2 nan 4 nan]
[/code]

Die vorliegenden NaN-Werte sollen jetzt ersetzt werden. Dazu soll der Mittelwert aus den gültigen Nachbarwerten (Süd,Nord,Ost,West,Nordost,Südost,Südwest,Nordwest) berechnet werden.

Für [code]A(2,2)[/code] würde sich ein Mittelwert von (3+3+2)/3=2.67 ergeben.

Weite sollen mindesten 3 gültige Nachbarwerte vorliegen um einen NaN-Wert zu ersetzen.

Mein Ansatz den ich habe funktioniert soweit, ist aber leider sehr aufwendig und unschön. Meine Frage ist, wie könnte ich beispielsweise auf die for-Schleifen verzichten.

Vielen Dank
Jonas

[code]
clc;
close all;
clear all;

A = [nan nan nan 4 5; nan nan 3 4 5; nan 2 3 4 5; 1 2 3 4 5; 1 2 nan 4 nan];
A_alt=A;
b=isnan(A);
c=sum(sum(b));
[z,s]=size(A);


while c~=0
for i =1:z
for k=1:s
% Feld E
if k>1 && k<s && i>1 && i<z && b(i,k)==1
f=zeros(3,3);
f=A(i-1:i+1,k-1:k+1);
% Feld A
elseif k==1 && i==1 && b(i,k)==1
f=zeros(2,2);
f=A(i:i+1,k:k+1);
% Feld B
elseif k==1 && i>1 && i<z && b(i,k)==1
f=zeros(3,2);
f=A(i-1:i+1,k:k+1);
% Feld C
elseif k==1 && i==z && b(i,k)==1
f=zeros(2,2);
f=A(i-1:i,k:k+1);
% Feld D
elseif i==1 && k>1 && k<s && b(i,k)==1
f=zeros(2,3);
f=A(i:i+1,k-1:k+1);
% Feld F
elseif i==z && k>1 && k<s && b(i,k)==1
f=zeros(2,3);
f=A(i-1:i,k-1:k+1);
% Feld G
elseif k==s && i==1 && b(i,k)==1
f=zeros(2,2);
f=A(i:i+1,k-1:k);
% Feld H
elseif k==s && i>1 && i<z && b(i,k)==1
f=zeros(3,2);
f=A(i-1:i+1,k-1:k);
% Feld I
elseif k==s && i == z && b(i,k)==1
f=zeros(2,2);
f=A(i-1:i,k-1:k);
end
h=sum(nansum(f));
g=sum(sum(isfinite(f))) ;
if b(i,k)==1 && g>2
A(i,k)= h/g;
else
A(i,k)= A(i,k);
end

end
end
b=isnan(A);
c=sum(sum(b));

end[/code]


Gast



Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.10.2014, 23:10     Titel:
  Antworten mit Zitat      
Moin

ganz auf die for-Schleife konnte ich nicht verzichten (aber ich bin mir sicher, dass das möglich ist), jedenfalls habe ich eine etwas elegantere Lösung gefunden:

Code:

% Beispielmatrix
A=[ nan nan nan 4 5;    ...
    nan nan 3   4 5;    ...
    nan 2   3   4 5;    ...
    1   2   3   4 5;    ...
    1   2   nan 4 nan   ];

% NaN-Indizes
idx = find(isnan(A));

% Matrixdimensionen (Anzahl der Reihen und Elemente)
nRow = size(A,1);
nEl = numel(A);

% Abstand der Nachbarindizes
mNeighbors = [-nRow-1   -1  nRow-1; ...
             -nRow     0   nRow;    ...
             -nRow+1   +1  nRow+1   ];
         
for ii = 1:length(idx)
    curIdx = idx(ii);
   
    if mod(curIdx-1, nRow) == 0
        % falls der aktuelle Index keine nördlichen Nachbarn hat
        curIdx = curIdx + mNeighbors(2:3,:);
    elseif mod(curIdx, nRow) == 0
        % falls der aktuelle Index keine südlichen Nachbarn hat
        curIdx = curIdx + mNeighbors(1:2,:);
    else
        % sonst
        curIdx = curIdx + mNeighbors;
    end
   
    % Indizes außerhalb der Matrix entfernen
    curIdx(curIdx>nEl) = [];
    curIdx(curIdx<1) = [];
   
    % interessante Werte aus Matrix holen
    curVal = A(curIdx);
   
    % NaNs raus
    curVal = curVal(~isnan(curVal));
   
    if numel(curVal) >= 3
        % falls 3 oder mehr gültige Nachbarn, Mittelwert berechnen
        A(idx(ii)) = mean(curVal);
    end
end
 


Ich vermute, auf die for-Schleife könnte man mittels
Code:
verzichten.

Viel Spass noch
 
Gast



Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.10.2014, 23:20     Titel:
  Antworten mit Zitat      
Ich habe übersehen, dass du da noch eine while-Schleife drumherum laufen lässt, die solange läuft, bis die Matrix komplett aufgefüllt ist.
Die fehlt bei meinem Code.
 
Jonas_Student

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.10.2014, 00:15     Titel:
  Antworten mit Zitat      
Hi,

vielen Dank für deine Antwort. Immerhin konntest du das ganze um eine for-Schleife reduzieren . Smile

Die aktuelle Version sieht nun wie folgt aus. Ein Kommilitone hat mir hierbei geholfen. Allerdings sind die Schleifen noch immer drin. Wink Ich probier weiter.

Code:

close all; clear all; clc;

A_start = [nan nan nan 4 5; nan nan 3 4 5; nan 2 3 4 5; 1 2 3 4 5; 1 2 nan 4 nan];
A_neu =A_start;
Umkreis = 1;
%A_neu = zeros(size(A_neu));
c=1;
while c~=0
for i = 1:size(A_neu,1)
    for j = 1:size(A_neu,2)
        Umkreis_Werte = A_neu(max((i-Umkreis), 1):min((i+Umkreis), end), max((j-Umkreis),1):min((j+Umkreis),end));
        if isnan(A_neu(i,j)) && length(find(~isnan(Umkreis_Werte))) >= 3;
            A_neu(i,j) = mean(Umkreis_Werte(~isnan(Umkreis_Werte)));
        else
            A_neu(i,j) = A_neu(i,j);
        end
    end
end
c=sum(sum(isnan(A_neu)));
end


Herzliche Grüße
Jonas
 
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.