将NaN值替换为矩阵

时间:2016-10-06 21:48:53

标签: matlab matrix interpolation

我有这个数据

Mat=[1 2 3 5;6 14 -9999 4;10 11 12 13;14 -9999 16 17;18 19 -9999 -9999]
Mat(Mat<0)=NaN

Mat =
1     2     3     5
6     14   NaN     9
10    11    12    13
14   NaN    16    17
18    19   NaN   NaN

我想用左右值的平均值替换NaN。我尝试转换向量中的所有矩阵,但de NaN的位置是importat所以这样做

Row = Mat(2,:)
Row = inpaint_nans(Row)

但错误显示

Undefined function 'inpaint_nans' for input arguments of type 'double'

结果必须像这样

Mat =
1     2     3     5
6     14    9     4
10    11    12    13
14    15    16    17
18    19   NaN   NaN

3 个答案:

答案 0 :(得分:1)

这是一个没有循环的选项:

Mat = [1 2 3 5;6 14 nan 4;10 11 12 13;14 nan 16 17;18 19 nan nan];
% get the transposed location of all NaNs:
loc = reshape(1:numel(Mat),size(Mat.')).'.*isnan(Mat);
% remove first and last column:
nan_loc = nonzeros(loc(:,2:end-1));
% replace them by the mean of the values to thier sides:
tMat = Mat.';
tMat(nan_loc) = mean([tMat(nan_loc-1) tMat(nan_loc+1)],2);
Mat = tMat.'

结果:

Mat =
     1     2     3     5
     6    14     9     4
    10    11    12    13
    14    15    16    17
    18    19   NaN   NaN

答案 1 :(得分:1)

[r,c]=find(isnan(Mat(:,2:end-1)));      % Finding indexes of NaN excluding the edges/corners
c=c+1; % To counter that we started from second column
for iter=1:length(c)
    Mat(r(iter),c(iter))= mean([Mat(r(iter),c(iter)-1)  Mat(r(iter),c(iter)+1)]);
end

答案 2 :(得分:1)

如果你有R2016a或更高版本,你可以这样做:

% Compute moving mean, omitting the NaNs
MatMean = movmean(Mat, 3, 2, 'omitnan');
InterpMat = Mat;
% Set NaN values to the average
InterpMat(isnan(Mat)) = MatMean(isnan(Mat));

这里唯一的打嗝是它并没有保留NaN s在你没有平均2个值的位置(也就是说,它没有取平均值19NaNNaN,而是19)。您可以通过后处理步骤来解决这个问题:

% Find regions where either neighbor of a NaN is NaN
N = size(Mat, 1);
mask = (movsum(isnan(Mat), [1 0], 2) == 2) | (movsum(isnan(Mat), [0 1], 2) == 2);
% Reset those points to NaN
InterpMat(mask) = NaN;