Replacing NaNs with zero in a matrix within a cell array.

조회 수: 66 (최근 30일)
Raza
Raza 2019년 1월 22일
댓글: Walter Roberson 2022년 10월 21일
How to replace NaNs with 0 in a cell array that has the following anatomy 13x1 cell, Each cell is of size 63x63[double]. the cell name is 'a'.
Any help would be appreciated, Thank you in advance.
  댓글 수: 2
Kevin Phung
Kevin Phung 2019년 1월 22일
what do you mean by the 'cell name'
Raza
Raza 2019년 1월 22일
the name of the cell array is 'a'. sorry for the confusion.

댓글을 달려면 로그인하십시오.

채택된 답변

Walter Roberson
Walter Roberson 2019년 1월 22일
a = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 0), a, 'uniform', 0);
No loop needed... just ugly code.
  댓글 수: 3
James Spalding
James Spalding 2022년 10월 19일
Hi Guys, I have a similiar problem but am getting errors prior to running from subsasgn:
"output must be assigned to a variable"
and after running get :
"Error using cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false."
I think it might be i don't understand the "M" variable which is used in the above solution. I've attached my cell variable {17x1} with uniform 362x292 matrices, also of note I am replacing the NaNs with a meaningless large number. I have tried switiching around M a destination variable as well as the call variable with NaNs.
I've attached the cell vairable and the code is below.
Any help here is greatly appreciated!
RvarNnan1 = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 123000), RvarNnan1, 'UniformOutput', 123000);
Walter Roberson
Walter Roberson 2022년 10월 21일
@James Spalding The number after the keyword 'UniformOutput' is treated as a logical switch. It is tested for being either 0 (meaning No, Not uniform output) or non-zero (meaning Yes, uniform output). So when you changed from 'UniformOutput', 0 (not uniform output) to 'UniformOutput', 123000 you were switching to "yes, uniform output". Which is not correct for this situation.
The M variable is a "dummy parameter".
a = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 0), a, 'uniform', 0);
means that each entry inside the cell named a is to be processed, with the content of each cell passed in turn as the first parameter to the anonymous function
@(M) subsasgn(M, substruct('()', {isnan(M)}), 0)
That anonymous function definition means that each time the anonymous function is executed, that a single parameter is to be accepted as input, and that everywhere inside the body of the code that the name M occurs it is to be replaced with what was passed in. The function handle is almost exactly equivalent to
@(varargin) subsasgn(varargin{1}, substruct('()', {isnan(varargin{1})}), 0)
-- that is, that the name of the variable M is not relevant (in nearly all conditions), that what is important is that it is the first parameter passed in that is being referred to, and what was passed in to the anonymous function is to be passed to first isnan() and later subsasgn() .
The reasons it is not exactly equivalent: (A) the @(varargin) version accepts extra parameters whereas the @(M) version errors if extra parameters are passed to the function; and (B) in the case where a named parameter is used, if a function is called that uses inputname then the name of the dummy parameter M can be retrieved, whereas if varargin is used, inputname() will return empty.
Functionally a = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 0), a, 'uniform', 0); is equivalent to
if exist('M', 'var')
SomeTemporaryInternalVariableName = M;
SomeOtherTemporaryInternalVariableName = true;
else
SomeOtherTemporaryInternalVariableName = false;
end
a = cell(size(a));
for K = 1 : numel(a)
M = a{K};
M = subsasgn(M, substruct('()', {isnan(M)}, 0);
a{K} = M;
end
if SomeOtherTemporaryInternalVariableName
M = SomeTemporaryInternalVariableName;
clear SomeTemporaryInternalVariableName
end
clear SomeOtherTemporaryInternalVariableName
which is to say, that the name M is used temporarily to hold the element during the calculation, and afterwards if M existed already, M is restored to its previous value.
M is not the name of the variable you are trying to work with.
The adjusted code for you should be
RvarNnan1 = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 123000), RvarNnan1, 'UniformOutput', 0);
but you should consider instead doing
RvarNnan1 = cellfun(@(M) fillmissing(M, 'constant', 123000), RvarNnan1, 'UniformOutput', 0);
as suggested by @Andy Campbell

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Omer Yasin Birey
Omer Yasin Birey 2019년 1월 22일
편집: Omer Yasin Birey 2019년 1월 22일
% a = cell(13,1);
% %initializing the values
% for i = 1:length(a)
% a{i} = nan(63,63);
% end
%removing the nans
for k = 1:size(a,1)
for j = 1:size(a,2)
a{k,j}(isnan(a{k,j}))=0;
end
end

Andy Campbell
Andy Campbell 2019년 3월 1일
편집: Andy Campbell 2019년 3월 1일
The fillmissing function is built for this, you just need to use cellfun since each of these doubles are included in the cell array.
nanless = cellfun(@(c) fillmissing(c,'constant',0), a,'UniformOutput',false)
If you don't want to use cellfun, since it looks like you data is all uniform you can also do this by putting each cell into an array, applyin fillmissing, and then reshaping it back into the cell array:
array = [a{:}]; % This works because they are all 63x63
array = fillmissing(array,'constant',0);
a = mat2cell(array, 63, ones(1,13)*63)
and of course this can all be one-lined
a = mat2cell(fillmissing([a{:}],'constant',0), 63, ones(1,13)*63);

카테고리

Help CenterFile Exchange에서 Line Plots에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by