mHelpMe
mHelpMe

Reputation: 6668

replace NaN in matrix with other values

I have a matrix called rf_rate. Some of the rows are NaN. I wish to replace these NaN's with a certain row of the rf_rate matrix. So far I have the code below which is not giving me the correct answer.

miss_rf = isnan(rf_rate);    % getting a logical matrix of where NaN's are

% this us_rf is a row from the rf_rate matrix (us_pos is a single number)
us_rf = repmat(rf_rate(us_pos, :), length(rf_rate(:, 1)), 1);

% this is where its going wrong
rf_rate(miss_rf==1, :)          = us_rf(miss_rf(miss_rf==1), :);

My matrix is of size 56x11 but after the last line it goes to 611x11, why?

In my matrix rf_rate there are two rows which are NaN it is these two rows I want to replace.

Upvotes: 2

Views: 211

Answers (2)

BillBokeey
BillBokeey

Reputation: 3476

If you have only entire rows with NaN values and 'clean' rows everywhere else :

% Number of rows to replace :
Nrows=sum(all(isnan(rf_rate),2));

% Replace the rows if Nrows>0:

if Nrows>0  

    rf_rate(all(isnan(rf_rate),2),:)=repmat(rf_rate(us_pos,:),Nrows,1);

end

If you have a row of reference and you want, everytime a NaN appears in any other row, to replace it with the corresponding value in your row of reference :

% Create a column vector of length `numel(rf_rate)` by repeating the first row :
Corrector=reshape(repmat(rf_rate(us_pos,:),size(rf_rate,1),1),[],1);

% Use linear indexing to fetch the NaN locations and replace them :
rf_rate(isnan(rf_rate(:)))=Corrector(isnan(rf_rate(:)));

Example 1 :

rf_rate=magic(10);
rf_rate([2 3 7],:)=NaN;
us_pos=1;

rf_rate =

    92    99     1     8    15    67    74    51    58    40
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
    85    87    19    21     3    60    62    69    71    28
    86    93    25     2     9    61    68    75    52    34
    17    24    76    83    90    42    49    26    33    65
   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
    79     6    13    95    97    29    31    38    45    72
    10    12    94    96    78    35    37    44    46    53
    11    18   100    77    84    36    43    50    27    59

% Apply code 1 :

% Number of rows to replace :
Nrows=sum(all(isnan(rf_rate),2));

% Replace the rows if Nrows>0:

if Nrows>0  

    rf_rate(all(isnan(rf_rate),2),:)=repmat(rf_rate(us_pos,:),Nrows,1);

end

Output

rf_rate =

    92    99     1     8    15    67    74    51    58    40
    92    99     1     8    15    67    74    51    58    40
    92    99     1     8    15    67    74    51    58    40
    85    87    19    21     3    60    62    69    71    28
    86    93    25     2     9    61    68    75    52    34
    17    24    76    83    90    42    49    26    33    65
    92    99     1     8    15    67    74    51    58    40
    79     6    13    95    97    29    31    38    45    72
    10    12    94    96    78    35    37    44    46    53
    11    18   100    77    84    36    43    50    27    59

Example 2 :

rf_rate=magic(10);
us_pos=1;
NanPos=randi(numel(rf_rate),10,1);
NanPos(mod(NanPos,10)==1)=[];
rf_rate(NanPos)=NaN;

rf_rate =

 92    99     1     8    15    67    74    51    58    40
 98    80     7    14    16    73    55    57    64    41
  4   NaN    88    20    22    54    56   NaN    70   NaN
 85    87    19    21     3    60    62    69    71    28
 86    93    25     2     9    61    68    75    52    34
 17    24    76    83    90    42    49    26    33    65
 23     5    82    89    91    48    30    32    39    66
 79     6    13    95    97    29    31    38    45    72
NaN    12    94   NaN   NaN    35    37    44   NaN    53
 11    18   NaN    77    84    36   NaN    50    27    59

% Apply code 2 :

% Create a column vector of length `numel(rf_rate)` by repeating the first row :
Corrector=reshape(repmat(rf_rate(us_pos,:),size(rf_rate,1),1),[],1);

% Use linear indexing to fetch the NaN locations and replace them :
rf_rate(isnan(rf_rate(:)))=Corrector(isnan(rf_rate(:)));

Output :

rf_rate =

    92    99     1     8    15    67    74    51    58    40
    98    80     7    14    16    73    55    57    64    41
     4    99    88    20    22    54    56    51    70    40
    85    87    19    21     3    60    62    69    71    28
    86    93    25     2     9    61    68    75    52    34
    17    24    76    83    90    42    49    26    33    65
    23     5    82    89    91    48    30    32    39    66
    79     6    13    95    97    29    31    38    45    72
    92    12    94     8    15    35    37    44    58    53
    11    18     1    77    84    36    74    50    27    59

Note that the second version of the code works for bot cases.

Upvotes: 1

Steve Heim
Steve Heim

Reputation: 809

I haven't figured out exactly what's happening with your code, but from your description I think what you want is

rf_rate(isnan(rf_rate)) = rf_rate(us_pos,:);

Note that unlike what you write, us_rf is not a row, but rather a matrix of the row repeated. Your code is taking that and inserting this several times.

Also note, this isn't particularly robust, and will fail if you have individual NaNs that don't take up an entire row.

Upvotes: 0

Related Questions