How to assign a NAN to an empty cell in a cell array of cell array of matrix

84 views (last 30 days)
I want to set NAN to these cells. Basically i wanted to do a basic threshold operation on a cell array of cell array of matrix . Some of the cells are empty cells, while others have values. If the absolute values in the cells are less than a threshold value say 5, i want to assign a zero to it. The problem is that the empty cells are also set to zero, which i do not want. So if we convert empty cell to NAN this problem can be solved. After the operation i can reassign NAN as an empty cell. But I am not able to perform this operation. I am able to do it in the first level based on previous discussion in the forum. for eg:
c={[] [] [2 4 5] [] [2 3 4 6 7]}% 1×5 cell array -- [] [] [1×3 double] [] [1×5 double]
fx=@(x)any(isempty(x))
ind=cellfun(fx,c)
c(ind)={nan}
I get
c =
1×5 cell array
[NaN] [NaN] [1×3 double] [NaN] [1×5 double]
Now for this example how can i do the same process?
c={{[] [1 2]} { [] [] [2 4 5]} {[] [2 3 4 6 7] []}}
c =
1×3 cell array
{1×2 cell} {1×3 cell} {1×3 cell}
When i follow the previous step I am getting the error "Function 'subsindex' is not defined for values of class 'cell'."
  2 Comments
James Tursa
James Tursa on 18 Feb 2017
Please also show the code you are currently using to do the threshold testing & 0 assigning.
GEEVARGHESE TITUS
GEEVARGHESE TITUS on 19 Feb 2017
I have just written a coarse threshold function and applied to my data using cellfun.
function y = sthresh(x)
[r c]=size(x);
t=0;
if not(isempty(x))
for i=1:r
for j=1:c
if abs(x(i,j))>5
t(i,j)=x(i,j);
else
t(i,j)=0;
end
end
end
end
y=real(double(t));

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 18 Feb 2017
Edited: Stephen23 on 19 Feb 2017
As per James' comment it would probably be more useful to fix your thresholding code so it works on empty cells as well.
Also note that in your example, the any is useless and fx could just be @isempty.
To answer your immediate question, you will have to use a loop:
for idx = 1:numel(c)
c{idx}(cellfun(@isempty, c{idx})) = {nan};
end
Or if you really want to use cellfun for the outer cell array, you will have to use a named function (in a file) as anonymous functions can't do assignment:
function c = empty2nan(c) %named function
c(cellfun(@isempty, c)) = {nan}
end
c = cellfun(@empty2nan, c, 'UniformOutput', false) %cellfun for outer cell array
The explicit loop is simpler, imo.
  6 Comments
Guillaume
Guillaume on 19 Feb 2017
"it is not skipping the empty or NAN cell, instead assigns zero to it."
Of course, it does. You've coded your function to make it so. Your function
function y = sthresh(x)
t = 0; %<----- set output to 0!
if ~isempty(x)
%do something
end
y = t;
end
When x is empty, you put 0 in y. The simple way to work around this problem is to do:
t = zeros(size(x)); %instead of 0.
Which would also fix two other problems with the loop: 1) your loop grew the t on each step of the loop. 2) your loop didn't work properly for arrays with more than 2 dimension.
But of course, the loop isn't needed at all. I also don't understand the purpose of the real(double(t)) conversion. Assuming it's not needed, the function could simply be:
function x = sthresh(x)
x(abs(x) <= 5) = 0;
end
which works on any size matrices, including empty ones. It also leaves NaN alone. If you want to change NaN to 0:
x(isnan(x) | abs(x) <= 5) = 0;

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!