How to perfrom indexing on nested cell array ?

Hallo, Thanks for reading!
I have a nested cell array S(1x9) >>
{2002x10 cell 1155x10 cell 3867x10 cell 4115x10 cell 5394x10 cell 3613x10 cell 3116x10 cell 1335x10 cell 7159x10 cell }
I used the follwoing code to find out the indices where 'abc' appears in 2nd column of nested cells. The result was as expected. However, my next step is to apply logical indices on each column of nested cells.
idx = cellfun(@(x) ismember(x,'abc'),s{1,i}(:,2))
Therefore, I used the following code and returned with the following error. Can please let me know where am I wrong?
cellfun(@(x) x(:,idx),s{1,1})
The logical indices in position 2 contain a true value outside of the array bounds.
Error in @(x)x(:,idx)

 Accepted Answer

Are you aware that cellfun looks really nice, but that the code runs faster with loops?
In your case you see, that a simple loop would simplify the code in addition. The easier the code, the more reliably it can be debugged.
for k = 1:numel(s)
idx = ismember(s{k}(:, 2), 'abc');
% Or maybe:
% idx = strcmp(s{k}(:, 2), 'abc');
t = s{k}(:, idx);
end

3 Comments

Thanks for the answer. I am always confused about which one to use for or cellfun.
With your method the loop returned with the following
Error using cell/ismember (line 34)
Input A of class cell and input B of class cell must be cell arrays of character vectors, unless
one is a character vector.
So I changed to this and it worked
ismember(string(s{k}(:, 2)),"abc");
Colud you tell a me bit more comparison of the speed between cell function and for loops? Is there an documentation. Thanks again.
Sorry for getting back again. It only worked for the first part
The half of the loop returned with the following error.
The logical indices in position 2 contain a true value outside of the array bounds.
Finally, it worked. I was doing it wrong by index colum instead of row. So the correct 2nd part would be.
t = s{k}(idx, :)

Sign in to comment.

More Answers (1)

Are you sure things are set up the way you intend? Here are some things I've noticed:
1) Your main problem is that you're defining idx with a column (size from 1155 to 7159), but your final call is looking at a row, so you're switching your indices. You only have 10 columns, but idx is sized from 1155 to 7159.
2) Although ismember works, you're going to get a return of a logic array for all elements in the specific column. It might be a bit more concise to call find() to just get the desired indices. This might be a personal preference thing for my coding style.
3) idx looks at specific elements of your top level cell array, but your final call looks only at the first cell. This will cause you problems when you have idx coming from a cell with more columns than s(1,1).

1 Comment

Thank your explanation! Actually you are right. My way of indexing at the end was wrong. I should have focused on row. It worked out now.

Sign in to comment.

Categories

Asked:

on 12 May 2021

Commented:

on 12 May 2021

Community Treasure Hunt

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

Start Hunting!