How to sepeperate a set of data to a new matrix from two set of matrix

Let,
A= [1 2 3 4 6 7 8 9; 10 11 12 13 14 15 16 17; 17 18 19 20 21 22 23 24]
B=[9 1; 17 1; 24 2]
I want to create a new set of matrix (say, C and D) consisting all the row values from matrix A based on the condition specified for matrix B:
Let [Row, Column 1] of Matrix B = B (:,1) = has different values;
[Row, Column 2] of Matrix B = B (:,2) = 1 or 2;
Column 2 of Matrix B has the same elements as Column 9 of Matrix A.
if [Row, Column 2] of Matrix B = B (:,2) = 1, then copy the entire row value of Matrix A corresponding to the [Row, Column 1] of Matrix B to a new Matrix C and so on...
and if [Row, Column 2] of Matrix B = B (:,2) = 2, then copy the entire row value of Matrix A corresponding to the [Row, Column 1] of Matrix B to a new Matrix D and so on...

2 Comments

Column 2 of Matrix B has the same elements as Column 9 of Matrix A.
From your above example, it would seem that Column 1 of B has the same elements as column 9 of A.
Ravi - you need to clarify the rules and provide examples at each step so that it is clear to you and us what you are trying to do.
Thank you Geoff...
Yes it is, Column 1 of B has the same elements as column 8 of A.
If Row1Column2 of Matrix B = 1, and it's corresponding Row1Column 1 of Matrix B = 9
then find the Row1Column1 value of Matrix B, (i.e, 9) in Matrix A (i.e., Row1Column8 of Matrix A) and copy the entire corresponding row of matrix A (i.e., row corresponding to value of 9 in Matrix A) to a new matrix (m).

Sign in to comment.

 Accepted Answer

Here is a generic way of splitting the original matrix into submatrices according to your condition:
function C = splitmatrix(A, B, indexcol)
%indexcol: a scalar integer >=1
%A: a M x N matrix, with N >= indexcol. the elements of A(:, indexcol)) must be unique
%B: a P x 2 matrix. Column 1 of B must match one value of A(:, indexcol). Column 2 of B must be integer >= 1
%C: cell array output of size max(B(:, 2) x 1.
%C{k} is a matrix whose rows are the rows of A for which A(:, indexrow) is found in B(1, B(:, 2) == k)
%validate above preconditions
validateattributes(indexcol, {'numeric'}, {'scalar', 'integer', 'positive'});
validateattributes(A, {'numeric'}, {'2d'});
assert(size(A, 2) >= indexcol, 'indexcol is greater than the number of columns of A');
assert(numel(unique(A(:, indexcol))) == size(A, 1), 'some elements of A(:, indexcol) are non unique');
validateattributes(B, {'numeric'}, {'2d', 'ncols', 2});
assert(all(ismember(A(:, indexcol), B(:, 1))), 'some elements of B(:, 1) are not found in A:, indexcol)');
validateattributes(B(:, 2), {'numeric'}, {'integer', 'positive'}, '', 'second column of B');
%find the rows of A that match first column of B:
Arows = arrayfun(@(indexval) find(A(:, indexcol) == indexval), B(:, 1));
%concatenate Arows according to the index in B(:, 2):
rowsdestination = accumarray(B(:, 2), Arows, [], @(v) {v});
%split A according to the destination:
C = cellfun(@(rows) A(rows, :), rowsdestination, 'UniformOutput', false);
end

5 Comments

Thank you Guillaume.
I am getting an error while running the code.
"Error using splitmatrix (line 9)
Not enough input arguments".
I would be grateful if you could suggest me on this....
As documented in the code comments, the function needs three input arguments:
A = [1 2 3 4 6 7 8 9; 10 11 12 13 14 15 16 17; 17 18 19 20 21 22 23 24];
B = [9 1; 17 1; 24 2];
C = splitmatrix(A, B, 8);
celldisp(C)
returns:
C{1} =
1 2 3 4 6 7 8 9
10 11 12 13 14 15 16 17
C{2} =
17 18 19 20 21 22 23 24
It worked great, thank you so much Guillaume. I have a slightly more difficult problem related to this. It will take some time for me to simplify the problem. I would be grateful to you if you could have a look on that as well.
Dear Guillaume, I posted the problem which I requested you to have a look just now in the answer section of the current topic. I would be grateful if you could have look on that as well...
Thanks Guillaume.....Posted as a separate question...I also removed the question asked in the answer section under current topic to avoid any confusion....

Sign in to comment.

More Answers (1)

Ravi - try the following
A = [1 2 3 4 6 7 8 9; 10 11 12 13 14 15 16 17; 17 18 19 20 21 22 23 24];
B = [9 1; 17 1; 24 2];
C = [];
% loop over each row of B
for k=1:size(B,1)
% if the second column of row k is one
if B(k,2) == 1
% get the row and column indices of A which match on B(k,1)
[ridx,cidx] = find(A == B(k,1));
if ~isempty(ridx)
% copy the row(s) of A to C
C = [C ; A(ridx,:)];
end
end
end
The result of running the above is
C =
1 2 3 4 6 7 8 9
17 18 19 20 21 22 23 24
10 11 12 13 14 15 16 17
We get three rows since 17 (the first element of the second column of B) is found in rows 2 and 3 of A.

1 Comment

Thank you for this. Is it possible to restrict the search to column 8 only as I would like to get my data sorted based on that. The final results should be something like:
for B(k,2)==1
C =
1 2 3 4 6 7 8 9
10 11 12 13 14 15 16 17
and for B(k,2)==2,
D=
17 18 19 20 21 22 23 24
Column-8_Row-3 of Matrix A = 24, which is Column-1_Row-3 of Matrix B and Column-2_Row-3 of Matrix B corresponds to above to a value 2.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 12 Apr 2015

Edited:

on 16 Apr 2015

Community Treasure Hunt

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

Start Hunting!