Replace NaNs with previous values
    30 Ansichten (letzte 30 Tage)
  
       Ältere Kommentare anzeigen
    
Hello,
I have the following problem. I like to replace NaNs with the previous values.
A =
     4     5     6     7     8
    32   NaN   NaN    21   NaN
    12   NaN    12   NaN   NaN
    34   NaN   NaN   NaN   NaN
B =
     4     5     6     7     8
    32     5     6    21     8
    12     5    12    21     8
    34     5    12    21     8
I sloved it like this:
for i = 2:5
[r,c] = find(isnan(A(:,i)));
while sum(isnan(A(:,i)))>0
A(r,i) = A(r-1,i);
end
end
I'm sure there is a way avoiding the for and the while statement. I search for an "elegant" solution.
Someone's able to help me?
2 Kommentare
Antworten (5)
  Moshe Flam
      
 am 3 Dez. 2017
        
      Bearbeitet: Moshe Flam
      
 am 4 Dez. 2017
  
          ROWBYROW = 2;
    B = fillmissing(A,'previous',ROWBYROW);
2 Kommentare
  Namrata Goswami
 am 11 Dez. 2020
				
      Bearbeitet: Namrata Goswami
 am 11 Dez. 2020
  
			This worked for me partially, since I need to replace missing values withing group. How to use fillmising within a group, like with splitapply  ?
  Matt Fig
      
      
 am 9 Okt. 2012
        
      Bearbeitet: Matt Fig
      
      
 am 9 Okt. 2012
  
      Johannes, notice that your solution will fail if the first value in a column is nan. Rather than looking for a vectorized solution that may end up being rather convoluted (and being slower!), I would simply write a good FOR loop function that can handle all cases. For example, the following solution does not use the FIND function, and only uses simple loops and thus should be very fast:
function A = fill_nans(A)
% Replaces the nans in each column with 
% previous non-nan values.
for ii = 1:size(A,2)
    I = A(1,ii);
    for jj = 2:size(A,1)
        if isnan(A(jj,ii))
            A(jj,ii) = I;
        else
            I  = A(jj,ii);
        end
    end
end
7 Kommentare
  Timothy Jackson
 am 1 Apr. 2016
				Is there a way to do this both before and after values? For instance changing
A= NaN NaN 2 4 8 NaN NaN to A= 2 2 2 4 8 8 8 ?
  Wayne King
    
      
 am 9 Okt. 2012
        
      Bearbeitet: Wayne King
    
      
 am 9 Okt. 2012
  
      How about:
 A = [ 4     5     6     7     8
    32   NaN   NaN    21   NaN
    12   NaN    12   NaN   NaN
    34   NaN   NaN   NaN   NaN];
 indices = isnan(A);
 A(indices) = 0;
 B = repmat([4 5 6 7 8],size(A,1),1);
 A = A+B.*indices;
1 Kommentar
  Matt Fig
      
      
 am 9 Okt. 2012
				Johannes comments:
"Solution there:
A =
     4     5     6     7     8
    32     5     6    21     8
    12     5    12     7     8
    34     5     6     7     8
Not good, would need the following: 4 5 6 7 8 32 5 6 21 8 12 5 12 21 8 34 5 12 21 8
Still thanks for you help!"
  owr
      
 am 9 Okt. 2012
        I do this all the time, my code uses for loops, but I dont see anything wrong with for loops. Im sure there are more elegent solutions but this does the trick for me and is more than fast enough:
function datai = backfillnans(data)
% Dimensions
[numRow,numCol] = size(data);
% First, datai is copy of data
datai = data;
% For each column
for c = 1:numCol
    % Find first non-NaN row
    indxFirst = find(~isnan(data(:,c)),1,'first');
    % Find all NaN rows
    indxNaN = find(isnan(data(:,c)));
    % Find NaN rows beyond first non-NaN
    indx = indxNaN(indxNaN > indxFirst);
    % For each of these, copy previous value
    for r = (indx(:))'
        datai(r,c) = datai(r-1,c);
    end
end
2 Kommentare
  Matt Fig
      
      
 am 9 Okt. 2012
				This seems to fail when a whole column of data is nan.
A = [25   NaN    54    99    20
     3   NaN    92    74    89
     7   NaN   NaN   NaN    82
     75   NaN    43    65    77
     NaN   NaN    15   NaN    38]
  owr
      
 am 9 Okt. 2012
				Ah, good catch Matt, thanks for that. Ive been using this for almost 2 years multiple times a day and thats never come up - I guess I never have a full column of nans. It can be fixed I guess by putting an:
if( ~isempty(indxFirst) )
after the line that calculates "indxFirst". Part of me would actually like the whole process to fail so I can figure out why I passed a full column of nans in the first place - that would be symptomatic of a much bigger issue...
Anyways, thanks for taking the time to run and test the code.
  Carlos Vladimir Rodriguez Caballero
 am 18 Jul. 2017
        I found your procedure much more elegant and efficient. It was very helpful man.
0 Kommentare
Siehe auch
Kategorien
				Mehr zu Structures finden Sie in Help Center und File Exchange
			
	Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!