Copy certain number from one matrix to another

3 views (last 30 days)
I have a matrix that i import from xlxs file using the code
function[output] = second()
[raw] = xlsread('errors168h.xlsx');
disp(raw)
A = raw(:,1);
B = raw(:,2);
output=[A,B];
end
and the matrix i got is
A B
1 1
2 1
3 1
4 2
5 2
6 2
7 1
8 1
9 2
10 2
11 2
How can i copy matrix from second column but only certain number? the other number will be random either 1 or 2. Example
A B | | A B
1 1 1 | | 1 1 1
2 1 1 | | 2 1 1
3 1 1 | | 3 1 1
4 2 2 | | 4 2 2
5 2 1 | OR | 5 2 2
6 2 1 | | 6 2 1
7 1 1 | | 7 1 1
8 1 1 | | 8 1 1
9 2 2 | | 9 2 2
10 2 2 | |10 2 1
11 2 1 | |11 2 1
If the third row of 2 become 1, the rest of the column will become 1. process repeat until it reach another set of 2. Whenever it read number 1 on column B, it will stop processing and when it will start changing number again when it read 2 on column B. In short, it do like this
A B A B C
------ -----------
1 1 1 1 1 %copy normally to C
2 1 2 1 1
3 1 3 1 1
4 2 4 2 2 %read 2 at B. random 1 or 2. get 2
5 2 5 2 1 %read 2 at B. random 1 or 2. get 1
6 2 6 2 1 %read 2 at B. Follow previous value and set 1
7 1 7 1 1 %read 1. copy normally value to C
8 1 8 1 1
9 2 9 2 1 %read 2 at B. random 1 or 2. get 1 (start process like previous)
10 2 10 2 1 %read 2 at B. Follow previous value and set 1
11 2 11 2 1 %read 2 at B. Follow previous value and set 1
  2 Comments
Massimo Zanetti
Massimo Zanetti on 3 Oct 2016
I really don't get what you need to do.. can you try tyo explain better? What is the difference between the two matrices just above?
Jane Mitchwell
Jane Mitchwell on 3 Oct 2016
The first matrix is the result i got. I want to copy the first matrix, second column to a new column. However i want certain number only be copied to the new column. The number 2 also will be copied but at the same time, i want it to be random either still 2 or it change to 1. If lets say the second row of number 2 is change to 1, the rest of the rows will also change to 1
1 1
1 1
2 2
2 1
2 1
1 1

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 3 Oct 2016
Edited: Stephen23 on 3 Oct 2016
This does the job perfectly, without any explicit loop:
A = [1:12;1,1,1,2,2,2,1,1,2,2,2,1]'
idx = A(:,2)==2 & [true;diff(A(:,2))==1];
idy = ~idx(1)+cumsum(idx);
tmp = accumarray(idy,A(:,2),[],@(n){n});
fun = @(v)[sort(randi(1:2,nnz(v==2),1),'descend');v(v==1)];
out = [A,cell2mat(cellfun(fun,tmp,'UniformOutput',false))]
And tested a few times:
out =
1 1 1
2 1 1
3 1 1
4 2 2
5 2 2
6 2 2
7 1 1
8 1 1
9 2 2
10 2 2
11 2 1
12 1 1
out =
1 1 1
2 1 1
3 1 1
4 2 2
5 2 2
6 2 1
7 1 1
8 1 1
9 2 2
10 2 1
11 2 1
12 1 1
out =
1 1 1
2 1 1
3 1 1
4 2 1
5 2 1
6 2 1
7 1 1
8 1 1
9 2 2
10 2 1
11 2 1
12 1 1
out =
1 1 1
2 1 1
3 1 1
4 2 2
5 2 1
6 2 1
7 1 1
8 1 1
9 2 2
10 2 1
11 2 1
12 1 1
...etc
  6 Comments
Jane Mitchwell
Jane Mitchwell on 4 Oct 2016
If i want to insert a new value (1,2,3) instead just 1 and 2, which part of the code i need to change?
Stephen23
Stephen23 on 13 Oct 2016
Edited: Stephen23 on 13 Oct 2016
@Jane Mitchwell: The answer to your question is most likely "change the function fun". If you want more help than that then please explain exactly what you require, with input and output examples.

Sign in to comment.

More Answers (3)

Massimo Zanetti
Massimo Zanetti on 3 Oct 2016
Edited: Massimo Zanetti on 3 Oct 2016
This version only requires one instance of ARRAYFUN
A = [1:12;2,1,1,2,2,2,1,1,2,2,2,1]';
I = (A(:,2)==2);
J = diff([0;I]);
E = I & J;
Z = cumsum(E)+~E(1);
C1 = accumarray(Z.*I+1,1); C1(1)=[];
C2 = accumarray(Z-Z.*I+1,1); C2(1)=[];
T = cell2mat( arrayfun( @(n) sort( [ randi(2,C1(n),1) ; ones(C2(n),1) ] , 'descend' ) , (1:max(Z))' , 'UniformOutput', false) );
out = [A,T]
  3 Comments
Jane Mitchwell
Jane Mitchwell on 4 Oct 2016
Out of curiosity, if i want to insert a new value (1,2,3) instead just 1 and 2, which part of the code i need to change?

Sign in to comment.


KSSV
KSSV on 3 Oct 2016
clc; clear all ;
A = [1 1
2 1
3 1
4 2
5 2
6 2
7 1
8 1
9 2
10 2
11 2];
% second row
a = A(:,2) ;
a_rand = a(randperm(length(a)));
B = [A a_rand]
Are you looking something like this?
  1 Comment
Jane Mitchwell
Jane Mitchwell on 3 Oct 2016
Apparently the code above change the number 1 to number 2. i was hoping the number 1 remain the same. here is the output i got
1 1 2
2 1 1
3 1 2
4 2 1
5 2 1
6 2 2
7 1 2
8 1 1
9 2 2
10 2 1
11 2 2
i try to change the code but i cant get the result like :
1 1 1
2 1 1
3 1 1
4 2 2
5 2 2
6 2 1
7 1 1
8 1 1
9 2 2
10 2 1
11 2 1

Sign in to comment.


Andrei Bobrov
Andrei Bobrov on 4 Oct 2016
Edited: Andrei Bobrov on 4 Oct 2016
out = A(:,[1,2,2]);
s = regionprops(bwlabel(A(:,2)-1),'PixelIdxList');
ii = {s.PixelIdxList};
jj = cellfun(@(ii)sort(randi(1:2,numel(ii),1),'descend'),ii,'un',0);
out(cat(1,ii{:}),3) = cat(1,jj{:});
  2 Comments
Jane Mitchwell
Jane Mitchwell on 5 Oct 2016
Can explain abit about the codes? and if i wanted to add new value (3) instead just 1 and 2, which part do i have to alter?
Andrei Bobrov
Andrei Bobrov on 5 Oct 2016
Yes.
A = [1:12;1,3,3,3,2,7,2,1,2,2,2,1]'
out = A(:,[1,2,2]);
[~,~,c] = unique(A(:,2));
s = regionprops(c,'PixelIdxList');
ii = {s.PixelIdxList};
jj = cellfun(@(ii)sort(randi([1,A(ii(1),2)],...
numel(ii),1),'descend'),ii,'un',0);
out(cat(1,ii{:}),3) = cat(1,jj{:});

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!