Eliminating zeros and NaNs from cell array

2 vues (au cours des 30 derniers jours)
Martyna
Martyna le 18 Juil 2017
Modifié(e) : Jan le 18 Juil 2017
Hello,
probably a stupid issue, but it takes long enough to ask you a question: I have a 1x6 cell array and in each of the six cells I have embedded 20 cells with numeric columns. I need to get rid of randomly distributed zeros and NaN values from each of the numeric column. The latest thing I have is this:
v2(i,num)(v2(i,num) == 0) = [];
- where v2_disc is a name of 1x6 cell array. Would somebody be able to tell me what is wrong?
Thank you!
  4 commentaires
Martyna
Martyna le 18 Juil 2017
Modifié(e) : Martyna le 18 Juil 2017
Here I am pasting a piece of the code, so you might get better idea of what I'm talking about:
pathFolder = '/Users/martyna/Desktop/DATA/';
d = dir(pathFolder);
isub = [d(:).isdir]; %# returns logical vector
nameFolds = {d(isub).name}';
nameFolds(ismember(nameFolds,{'.','..'})) = [];
%%creating empty cells for filling with values later
v1_disc = cell(1,length(nameFolds));
v2_disc = cell(1,length(nameFolds));
%%for loop going through all the subjects
for i=1:length(nameFolds)
cd([pathFolder, nameFolds{i,1}, '/Both'])%
listing_DISC = dir('Disconnected/*.txt');
x = cell(1,size(listing_DISC,1));
NT = size(listing_DISC,1);
v1_disc{i} = cell(1,NT);
v2_disc{i} = cell(1,NT);
for num = 1:NT
cd(listing_DISC(num).folder);
x{num}=load(listing_DISC(num).name);
v1_disc{i}{num} = sqrt(vx1.^2 + vy1.^2);
v2_disc{i}{num} = sqrt(vx2.^2 + vy2.^2);
end
...
end
- in the end, I need to get rid of zeros and NaNs in v2_disc.
Guillaume
Guillaume le 18 Juil 2017
Modifié(e) : Guillaume le 18 Juil 2017
Small point:
[d(:).isdir]
the (:) is unnecessary,
[d.isdir]
works just as well.
Note that you could shorten the whole nameFolds generation to:
d = dir(pathFolder);
nameFolds = {d([d.isdir] & ~ismember({d.name}, {'.', '..'})).name};
Second small point: avoid cd. It'll be faster and safer to build the full path of the files and use that with load or dir, e.g.:
for i = 1:numel(nameFolds)
currentpath = fullfile(pathFolder, nameFolds{i}, 'Both');
listing_DISC = dir(fullfile(currenpath, 'Disconnected', '*.txt'));
%...
cd is slow and you run the risk of popping functions in and out of existence. For example, if you cd into a folder with a sqrt.m file, matlab will use that instead of the built-in sqrt.
Third small point: listing_DISC and nameFolds vectors. It is safer to use linear indexing and numel (or length if you must) rather than 2d indexing and size with a specific dimension. The following works whether the vectors are rows, columns, or along any other dimension:
nameFolds{i}
NT = numel(listing_DISC)
whereas
nameFolds{i, 1}
NT = size(listing_DISC, 1)
will fail if the vectors are anything but columns.

Connectez-vous pour commenter.

Réponses (4)

KSSV
KSSV le 18 Juil 2017
You can follow up something like this...don't get confused with the first part of the code..I am manually creating random data for demo.
V2 = cell(1,6) ;
% make random data for demo
for i = 1:6
T = rand(randperm(10,1)) ;
N = numel(T) ;
if N>5
T(randperm(N,3)) = 0 ;
T(randperm(N,4)) = NaN ;
end
V2{i} = T ;
end
V0 = V2 ;
%%remove NaNs and zeros
for i = 1:6
T = V2{i} ;
T(T==0) = [] ;
T(isnan(T)) = [] ;
V2{i} = T ;
end
  1 commentaire
Jan
Jan le 18 Juil 2017
Perhaps this is not "1x6 cell array and in each of the six cells I have embedded 20 cells with numeric columns".

Connectez-vous pour commenter.


Guillaume
Guillaume le 18 Juil 2017
Modifié(e) : Guillaume le 18 Juil 2017
Answer edited following the edit to the question:
If v2 is a cell array of any size, then
v2(i, num)
is a 1x1 cell array. It's still a container, you're not looking at the content. Therefore,
v2(i, num) == 0
is going to result in an error, since matlab does not know what a cell array (a container) being equal to zero mean. If you want to look at the content of a cell array you need to use curly braces {}:
v2{i, num}
This is will be whatever is in the cell array at i, num.
edited answer starts here:
if you have a cell array of cell arrays containing vectors, you get rid of the nans and 0 with:
for folder_idx = 1:numel(v2_disc)
for file_idx = 1:numel(v2_disc{folder_idx})
filecontent = v2_disc{folder_idx}{file_idx};
v2_disc{folder_idx}{file_idx} = filecontent(~isnan(filecontent) & filecontent ~= 0);
end
end
Note that this is pretty much the same as Jan's answer
Or you could use cellfun:
v2_disc = cellfun(@(foldercontent) cellfun(@(filecontent) filecontent(~isnan(filecontent) & filecontent ~= 0), ...
foldercontent, ...
'UniformOutput', false), ...
v2_disc, 'UniformOutput', false);
Or you could get rid of these NaN and 0s before you store your vectors in the cell arrays.
See also my comments at the end of your question.

Jan
Jan le 18 Juil 2017
Modifié(e) : Jan le 18 Juil 2017
Perhaps:
innerData = [rand(10, 1); zeros(5, 1); nan(5, 1)];
innerData = innerData(randperm(10, 10));
innerCell = cell(1, 20);
innerCell(:) = {innerData};
outerCell = repmat(innerCell, 1, 6);
If this is equivalent to your inputs, add another loop to KSSV's solution:
C = outerCell;
for iC = 1:6
for iC2 = 1:20
T = C{iC}{iC2};
V2{iC}{iC2} = T(T ~= 0 & ~isnan(T));
end
end
By the way: T(T ~= 0 & ~isnan(T)) can be written as ([EDITED] but it should not, because "T(T ~= 0 & ~isnan(T)" is much easier to read!):
T(T & T==T)
  2 commentaires
Guillaume
Guillaume le 18 Juil 2017
Modifié(e) : Guillaume le 18 Juil 2017
By the way: T(T ~= 0 & ~isnan(T)) can be written as:
T(T & T==T)
Not without a comment explaining that it tests for non-zero and non-nans! Otherwise the next person reading/debugging the code will have to puzzle over what is going on. Whenever using shortcuts like these, always comment them.
Jan
Jan le 18 Juil 2017
Modifié(e) : Jan le 18 Juil 2017
@Guillaume: You are right. "T(T&T==T)" has an aesthetic value, but for reading and understanding the code it is junk, because the intention of the code is obfuscated. Even if this would be some micro-seconds faster in the execution, it wastes seconds during reading and debugging.

Connectez-vous pour commenter.


Martyna
Martyna le 18 Juil 2017
To clarify: I want to access vectors that are in cell arrays which are again stored in a cell array structure. I tried @Jan's method, but error connected with using '==' for cells still pops up.
  1 commentaire
Guillaume
Guillaume le 18 Juil 2017
Please, use Comment on this Answer rather than starting a new answer.
Jan's answer does not have == in its code, so you're obviously using something different. It looks to me that Jan's answer matches exactly the data structure you're describing.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by