Copy certain number from one matrix to another

3 Ansichten (letzte 30 Tage)
Jane Mitchwell
Jane Mitchwell am 3 Okt. 2016
Bearbeitet: Stephen23 am 13 Okt. 2016
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 Kommentare
Massimo Zanetti
Massimo Zanetti am 3 Okt. 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 am 3 Okt. 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

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Stephen23
Stephen23 am 3 Okt. 2016
Bearbeitet: Stephen23 am 3 Okt. 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 Kommentare
Jane Mitchwell
Jane Mitchwell am 4 Okt. 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 am 13 Okt. 2016
Bearbeitet: Stephen23 am 13 Okt. 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.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

Massimo Zanetti
Massimo Zanetti am 3 Okt. 2016
Bearbeitet: Massimo Zanetti am 3 Okt. 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 Kommentare
Massimo Zanetti
Massimo Zanetti am 3 Okt. 2016
Yes, you are right..
Jane Mitchwell
Jane Mitchwell am 4 Okt. 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?

Melden Sie sich an, um zu kommentieren.


KSSV
KSSV am 3 Okt. 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 Kommentar
Jane Mitchwell
Jane Mitchwell am 3 Okt. 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

Melden Sie sich an, um zu kommentieren.


Andrei Bobrov
Andrei Bobrov am 4 Okt. 2016
Bearbeitet: Andrei Bobrov am 4 Okt. 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 Kommentare
Jane Mitchwell
Jane Mitchwell am 5 Okt. 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 am 5 Okt. 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{:});

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by