Get n-th value from a double array in a cell array

3 views (last 30 days)
Hi all,
i've a 200*200 cell array (test) with a n*1 double array in each, some cells are empty as well. I want to get the 5th value of the double (5,1).
1) Generate Index with only non-empty elements:
fct = @(d) find(d > 0, 1, 'first');
IndUpdates = cellfun(fct, test, 'Uni', 0);
2) Get size of Double Arrays
fct2 = @(idx, d) size(d,1);
IndSize = cellfun(fct2, IndUpdates, test, 'Uni', 0);
--> what is the 'idx' for? it does not run without it
3) Generate Index for cells with double arrays bigger than 5 elements
fct3 = @(d) find(d > MinUpdates, 1, 'first');
idxsus = cellfun(fct3, IndUpdates, test, 'Uni', 0);
until here it works fine. now i want the 5th value from every double array indexed by "idxsus". I thougt it would work like below, but it doesn't. (Error: Too many input arguments)
fct4 = @(d) d(MinUpdates,1);
result = cellfun(fct4, idxsus, test, 'Uni', 0);
I'm no matlab expert (as you can see) - is there anyone, who can fix my code with a little explanation?
Thank you in advance!
Florian

Accepted Answer

Jan
Jan on 22 Jul 2018
Edited: Jan on 22 Jul 2018
Why do you get the indices of non-empty cells, if you check again, if the length is greater than MinUpdates? The latter is sufficient. But it is not clear, why you assume that:
@(d) find(d > 0, 1, 'first')
finds empty cell elements. It checks for elements, which are greater than 0.
fct2 = @(idx, d) size(d,1);
IndSize = cellfun(fct2, IndUpdates, test, 'Uni', 0);
--> what is the 'idx' for? it does not run without it
You provide two inputs to cellfun: IndUpdates and test. Then cellfun calls the anonymous function with two arguments also. But why do you provide IndUpdates here?
What is the meaning and values of MinUpdates?
It is hard to understand the purpose of the code. What about a simple loop?
result = cell(size(test));
want = 5;
for k = 1:numel(test)
x = test{k};
if numel(x) >= want
result{k} = x(want);
end
end
If you really like cellfun:
want = 5;
match = cellfun('prodofsize', test) >= want;
result = cell(size(test));
result(match) = cellfun(@(c) c(want), test(match), 'UniformOutput', false)
Note: The "old" style cellfun('prodofsize', test) is more efficient than using an anonymous function or function handle like:
cellfun(@(c) numel(c), test)
cellfun(@numel, test)
  1 Comment
Florian R.
Florian R. on 24 Jul 2018
I thought that size() on a empty cell-array will result in an error, but you're (of course) right, it does not. My first try was to first catch all cells which are not empty and then get the size of the double-arrays in it.
Thanks for your explaining about the anonymous function.
The meaning of MinUpdates is corresponding to want in your example (so the 6th, 7th, ... element from the double array which i want to have in the result)
The Cell-Array mostly has ~ 200*200*100 Elements, i simply thought, that a loop is slower.
Sorry, but i still do not understand, why this
fct2 = @(idx, d) size(d,1);
IndSize = cellfun(fct2, IndUpdates, test, 'Uni', 0);
works an this
fct4 = @(idx, d) d(MinUpdates,1);
result = cellfun(fct4, idxsus, test, 'Uni', 0);
not. Both, idxsus and IndUpdates, are a Cell-Index. In the first case, if the size function size() is applied it's okay. Both size(d,1) and d(MinUpdates,1) returning one single value. Is it, because d(MinUpdates,1) is no function? (Would it be possible to write it as function?)
Anyhow, i did it like you suggested, 'prodofsize' makes it a lot easier, also the predefinition of cell-arrays is important.
Thank you! Florian

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 22 Jul 2018
MinUpdates = 5;
lengths = cellfun(@length, test);
idxsus = find(lengths >= MinUpdates);
result = cellfun(@(d) d(MinUpdates), test(idxsus));
I would not typically use find() for this, but it is useful if you need the linear indices of which cells you are pulling the information out of.

Products


Release

R2015b

Community Treasure Hunt

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

Start Hunting!