How to select only some sections of a matrix?

19 Ansichten (letzte 30 Tage)
MRC
MRC am 28 Apr. 2014
Kommentiert: the cyclist am 28 Apr. 2014
Hi, I have the matrix
C=[1 1; 1 2; 1 2; 1 3; 2 4; 2 5; 2 5; 2 6; 3 7; 3 8; 3 9; 3 10; 4 11; 4 12; 4 13; 4 14; 5 15; 5 16; 5 16; 5 17; 6 18; 6 19; 6 19; 6 20]
and
A=[6; 3; 1; 6; 6; 4]
I want to construct B such that it selects the elements of the second column of C checking the correspondence between the elements of the first column of A and C, i.e.
B=[18; 19; 19; 20; 7; 8; 9; 10; 1; 2; 2; 3; 18; 19; 19; 20; 18; 19; 19; 20; 11; 12; 13; 14]
without using loops. Could you help me?
  1 Kommentar
Image Analyst
Image Analyst am 28 Apr. 2014
Don't worry about for loops. If you have a method using for loops I'm sure it can do this in a trillionth of an atosecond. The non-for loop method may even be slower. But anyway, I can't follow how you got the elements of B. Can you describe how you got the first 3 or 4 elements of B in detail?

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

the cyclist
the cyclist am 28 Apr. 2014
C=[1 1; 1 2; 1 2; 1 3; 2 4; 2 5; 2 5; 2 6; 3 7; 3 8; 3 9; 3 10; 4 11; 4 12; 4 13; 4 14; 5 15; 5 16; 5 16; 5 17; 6 18; 6 19; 6 19; 6 20];
A=[6; 3; 1; 6; 6; 4];
[~,idx1] = ismember(A,C(:,1));
idx2 = bsxfun(@plus,idx1,0:3)';
B = C(idx2,2)
I relied on certain aspects of the structure of your input data, like the fact that each element in the first column of C was replicated 4 times.
  2 Kommentare
MRC
MRC am 28 Apr. 2014
Thank you for your help but the last row of the code does not work. I think I have to reshape idx2 in a column vector.
the cyclist
the cyclist am 28 Apr. 2014
Hm. Strange. Works for me. You could try
B = C(idx2(:),2)
instead.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Geoff Hayes
Geoff Hayes am 28 Apr. 2014
Bearbeitet: Geoff Hayes am 28 Apr. 2014
Hi Cris,
There are a couple of commands that may do what you want, but I'm not sure if you can completely avoid the for loops (someone else may have a better idea). The ismember command (type help ismember) is described as:
LIA = ismember(A,B) for arrays A and B returns an array of the same
size as A containing true where the elements of A are in B and false
otherwise.
So you could do something like C(ismember(C(:,1),A),2) and that would return all the elements in the second column of C whose first column value is in A. Of course, this is not the same as your B (order is wrong and doesn't handle the duplicate 6 in A). But with a loop you could do something…
An alternative is to use the bsxfun command (type help bsxfun) which is described as:
bsxfun Binary Singleton Expansion Function
C = bsxfun(FUNC,A,B) applies the element-by-element binary operation
specified by the function handle FUNC to arrays A and B, with singleton
expansion enabled. FUNC can be one of the following built-in functions:
Try running Z=bsxfun(@eq,C(:,1),A') from the command window. (Note that A has been transposed.) It will return a matrix with the number of columns equal to the length of A and the number of rows equal to the number of rows in C. For any one column i, if the value is zero, then that row element does not match A(i). Else if the value is one, then that row element does match A(i). Note that C(Z(:,1),2) returns the first four elements of your vector B, C(Z(:,2),2) the next four elements, etc. So you could loop over Z to construct your B.
Either way, there is still (for this answer) one for loop.
Geoff

Kategorien

Mehr zu Matrix Indexing finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by