Indexing a cell array according to another cell array

So I have two cell arrays, each represent onset and offset times of events, so they have the same size and they correspond to each other, for example:
A = {[2,3,4],[3,6],[5,7,9,10]};
B = {[2.5,4.2,4.7],[3.2,7.4],[6.2,7.6,9.4,11.3]}
I now was able to delete certain entries in A according to a different indexing vector c,let's say new A is (anything equals to 3 or between 7 to 9 is deleted):
A = {[2,4],[6],[5,10]}
How do I delete the corresponding entries in B? I want to achieve:
B = {[2.5,4.7],[7.4],[6.2,11.3]}
In other words delete the second, first, and second and third entires in the three cells in B. I tried to do it after entries were deleted from A, but the sizes and entries no longer match. It seems I have to somehow index A and B at the beginning before I mess with A, but I am not sure how to do this...

 Accepted Answer

n = repelem(1:numel(A),cellfun(@numel,A));
B1 = [B{:}];
A1 = [A{:}];
t = A1 ~= 3 & (A1 < 7 | A1 > 9);
out = accumarray(n(t)',B1(t),[],@(x){x});
or
n = repelem(1:numel(A),cellfun(@numel,A))';
C = [n(:),[A{:}]',[B{:}]'];
C = C(C(:,2) ~= 3 & (C(:,2) < 7 | C(:,2) > 9),:);
[ii,jj] = ndgrid(C(:,1),1:2);
out = accumarray([ii(:),jj(:)],reshape(C(:,2:3),[],1),[],@(x){x});

More Answers (1)

A = {[2,3,4],[3,6],[5,7,9,10]};
B = {[2.5,4.2,4.7],[3.2,7.4],[6.2,7.6,9.4,11.3]}
idx=cellfun(@(x) x~=3 & ~(x<=9 & x>=7),A,'un',0)
C1=cellfun(@(x,y) x(y),A,idx,'un',0)
C2=cellfun(@(x,y) x(y),B,idx,'un',0)
celldisp(C1)
celldisp(C2)

10 Comments

Thank you! This works! I have one other question and hope you could help...I am trying to use a logical vector as my constrain (instead of x=3 or x<=9 and x>=7), for example C = [0,0,1,0,0,0,1,1,1,0,0,0], how do I rewrite idx? Thank you so much!!!
Sorry in your previous answer
idx=cellfun(@(x) x~=3 & ~(x<=9 & x>=7),A,'un',0)
I just wanted to change this so I can index according to C
And how to apply C to your cell array?
A = {[2,3,4],[3,6],[5,7,9,10]}.
The elements in the cell array are time points in a time series from 0 to 10.
C = [0,0,1,0,0,0,1,1,1,0,0,0],
which contains 10 elements (same as the size of the time series). I want to remove any element in A (and corresponding ones in B) that corresponding to a "1" in C (x=3, or x>=7 and <=9). The result would be the same as your original solution:
A = {[2,4],[6],[5,10]},
B = {[2.5,4.7],[7.4],[6.2,11.3]}.
Thanks!
C does not contain 10 element but 12.
I am sorry please ignore the last 2 zeros. C = [0,0,1,0,0,0,1,1,1,0]. Actually it doesn't matter too much in this case.
Ok, but A contains just 9 elements!
I was using
A1=cellfun(@(x) x(~ismember(x,find(C))),A,'uni',false)
but it returns the final result I want but not index like your code did, so I can't apply it to B,and not sure how to fix it.
To make your question clear, post an example and explain clearly what you want, and post the expected result

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!