Slicing 2D array based on conditions specified in a seperate list

I have 2D (NxM) matrix with N rows and M columns (the dimensions depend on experimental data I collect, for example see matrix A below:
A = [1 0 0 1 0; 0 1 0 1 0 ; 1 0 0 1 1; 0 0 0 1 1]
Information about the identity of each row is specified by another Nx1 column vector, for example see matrix L below.
L = [A1 C4 F7 E5]*
So, row 1 of matrix A belongs to group "A1", row 2 belongs to group "C4" and so on.
I would like to create a slice of matrix A that contains specific rows that I specify from vector L.The grouping terms depend on experimental data, but I would like the ability to generate a series of slices based on specific elements of vector L that I define.
For example, I would like slice of matrix A containing only groups "A1" and "F7" from vector L to form the in a new 2xM matrix S. :
S = [1 0 0 1 0; 1 0 0 1 1]
I would appreciate some advice on how to do generic slicing of matrix A by using a subset of group identifiers from vector L. Any feedback would be much appreciated.

 Accepted Answer

Hi Sharf
1.
Input matrices
A = [1 0 0 1 0; 0 1 0 1 0 ; 1 0 0 1 1; 0 0 0 1 1]
L = ['A1' ;'C4'; 'F7'; 'E5']
2.
decide where to slice with for instance vector called query
query=[C4]
or
query='C4'
3.
thin slice, just one layer
A(find(sum(bsxfun(@eq,L,query),2)==2),:)
4.
a thicker slice, for instance
query=['A1';'F7';'A1']
now
[sz1 sz2]=size(query)
D=[];
for k=1:1:sz1
D=[D;find(sum(bsxfun(@eq,L,query(k,:)),2)==2)];
end
D contains the amount of occurrences
D =
1
3
1
.
since in your question it's not mentioned whether you want the resulting matrix to take into account repetitions or not, I am showing you both
5.
taking into account repetitions
A(D,:)
=
1 0 0 1 0
1 0 0 1 1
1 0 0 1 0
6.
considering repeated request for same row but ordering them with sort
A(sort(D),:)
=
1 0 0 1 0
1 0 0 1 0
1 0 0 1 1
7.
without taking into account repeated query for same row:
A(unique(D),:)
=
1 0 0 1 0
1 0 0 1 1
with best hope of having helped solve your question,
if you find this answer useful would you please be so kind to mark my answer as Accepted Answer?
To any other reader, please if you find this answer of any help solving your question,
please click on the thumbs-up vote link,
thanks in advance
John BG

1 Comment

This line:
A(find(sum(bsxfun(@eq,L,query),2)==2),:)
displays the MLint warning concerning the unnecessary find. You can simply omit it to use the faster logical indexing.
The lines:
D=[];
for k=1:1:sz1
D=[D;find(sum(bsxfun(@eq,L,query(k,:)),2)==2)];
end
let grow the output D in each iteration. This wastes resources and a "pre-allocation" (search for this term in the forum) is recommended:
D = zeros(1,sz1);
for k = 1:sz1
D(k) = find(sum(bsxfun(@eq,L,query(k,:)),2)==2);
end

Sign in to comment.

More Answers (1)

Keys = {'A1', 'C4', 'F7', 'E5'};
Data = [1 0 0 1 0; 0 1 0 1 0 ; 1 0 0 1 1; 0 0 0 1 1];
WantedKeys = {'A1', 'F7'};
[found, index] = ismember(WantedKey, Keys);
WantedData = Data(index, :)
[EDITED] Taken from Stephen Coboldick's comment: If the Keys are not unique, the order of the arguments for ismember are changed:
Keys = {'A1', 'C4', 'F7', 'A1'};
WantedKeys = {'A1', 'F7'};
Data = [1 0 0 1 0; 0 1 0 1 0 ; 1 0 0 1 1; 0 0 0 1 1];
index = ismember(Keys, WantedKeys);
Result = Data(index, :)
ans =
1 0 0 1 0
1 0 0 1 1
0 0 0 1 1

3 Comments

this works, but if the data keys are: keys = {'A1', 'C4', 'F7', 'A1'};
and WantedKeys = {'A1', 'F7'};
Wanted data will not include the last row.
Is there a quick way to include for redundant key names? your feedback would be appreciated, I like how simple the code is.
>> Keys = {'A1', 'C4', 'F7', 'A1'};
>> WantedKeys = {'A1', 'F7'};
>> Data = [1 0 0 1 0; 0 1 0 1 0 ; 1 0 0 1 1; 0 0 0 1 1];
>> index = ismember(Keys,WantedKeys);
>> Data(index,:)
ans =
1 0 0 1 0
1 0 0 1 1
0 0 0 1 1
@Tal Sharf: note that Jan Simon's solution is a much better concept than doing this in a loop.

Sign in to comment.

Asked:

on 2 Feb 2017

Edited:

Jan
on 7 Feb 2017

Community Treasure Hunt

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

Start Hunting!