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

36 visualizaciones (últimos 30 días)
Raza
Raza el 22 de En. de 2019
Comentada: Walter Roberson el 21 de Oct. de 2022
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 comentarios
Kevin Phung
Kevin Phung el 22 de En. de 2019
what do you mean by the 'cell name'
Raza
Raza el 22 de En. de 2019
the name of the cell array is 'a'. sorry for the confusion.

Iniciar sesión para comentar.

Respuesta aceptada

Walter Roberson
Walter Roberson el 22 de En. de 2019
a = cellfun(@(M) subsasgn(M, substruct('()', {isnan(M)}), 0), a, 'uniform', 0);
No loop needed... just ugly code.
  3 comentarios
James Spalding
James Spalding el 19 de Oct. de 2022
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 el 21 de Oct. de 2022
@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

Iniciar sesión para comentar.

Más respuestas (2)

Omer Yasin Birey
Omer Yasin Birey el 22 de En. de 2019
Editada: Omer Yasin Birey el 22 de En. de 2019
% 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 el 1 de Mzo. de 2019
Editada: Andy Campbell el 1 de Mzo. de 2019
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);

Categorías

Más información sobre Line Plots en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by