Subract specific areas from array
1 vue (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I would like to find and define specific areas in an array. For example for the next array;
Array = [0 0 0 0 2 2 1 1 1 2 2 2 2 2 2 2 2 1 1 1 2 2 0 2 2 0 0 0]
i would like to define the area's with connected 2's and divide them in two groups (the area of 2's which which is limited by two 1's, and the 2's which aren't closed by two ones, but for example two zeros or a one and a zero).
In the end i would like to keep the area which is closed in by two ones and dump the rest of my array
What would be the best way to do this?
2 commentaires
Jos (10584)
le 6 Jan 2014
Modifié(e) : Jos (10584)
le 6 Jan 2014
What do you mean by "divide in two groups" and "dump the rest"?
It would help if you'd also given an example of the expected outcome, like:
ArrayIn = [0 0 0 0 2 2 1 1 1 2 2 2 2 2 2 2 2 1 1 1 2 2 0 2 2 0 0 0]
ArrayOut = [0 0 0 0 0 0 1 1 1 2 2 2 2 2 2 2 2 1 1 1 0 0 0 0 0 0 0 0] %?
Réponse acceptée
Azzi Abdelmalek
le 6 Jan 2014
Modifié(e) : Azzi Abdelmalek
le 7 Jan 2014
A= [1 2 2 1 1 1 2 2 2 2 2 1 1 2 2 0 2 2 0 0 0 1 2 2 2 1 0 1 ];
ArrayOut1=zeros(size(A));
ArrayOut2=ArrayOut1;
idx1=union(strfind(A,[1 2]),strfind(A,[0 2]));
idx2=union(strfind(A,[2 1]),strfind(A,[2 0]))+1;
v=all(A([idx1' idx2']),2);
ArrayOut1(cell2mat(arrayfun(@(x) idx1(x)+1:idx2(x)-1,find(v)','un',0)))=2;
ArrayOut2(cell2mat(arrayfun(@(x) idx1(x)+1:idx2(x)-1,find(~v)','un',0)))=2;
Or in case A start (or/and) ends with 2
A= [2 2 1 1 1 2 2 2 2 2 1 1 2 2 0 2 2 0 0 0 1 2 2 2 1 0 1 2 ];
ArrayOut1=zeros(size(A));
ArrayOut2=ArrayOut1;
A=[0 A 0];
idx1=union(strfind(A,[1 2]),strfind(A,[0 2]));
idx2=union(strfind(A,[2 1]),strfind(A,[2 0]))+1;
v=all(A([idx1' idx2']),2);
ArrayOut1(cell2mat(arrayfun(@(x) idx1(x):idx2(x)-2,find(v)','un',0)))=2
ArrayOut2(cell2mat(arrayfun(@(x) idx1(x):idx2(x)-2,find(~v)','un',0)))=2
Plus de réponses (3)
Walter Roberson
le 6 Jan 2014
nonz = [0 (ArrayIn ~= 0) 0];
begin_groups = strfind(nonz, [0 1]);
end_groups = strfind(nonz, [1 0]);
Now look at the locations indicated by begin_groups and see if [2 2] starts there; likewise look in the corresponding end_groups and see if it ends with [2 2]
0 commentaires
Azzi Abdelmalek
le 6 Jan 2014
ArrayIn= [0 0 0 0 2 2 1 1 1 2 2 2 2 2 2 2 2 1 1 1 2 2 0 2 2 0 0 0 ]
B=num2str(ArrayIn);
B=strrep(B,' ','');
[ii1,ii2]=regexp(B,'(?<=1)2+(?=1)','start','end');
[jj1,jj2]=regexp(B,'(?<=0)2+(?=0)|(?<=0)2+(?=1)|(?<=1)2+(?=0) ','start','end');
ArrayOut1=zeros(size(ArrayIn));
ArrayOut2=ArrayOut1;
ArrayOut1(cell2mat(arrayfun(@(x,y) x:y,ii1,ii2,'un',0)))=2
ArrayOut2(cell2mat(arrayfun(@(x,y) x:y,jj1,jj2,'un',0)))=2
0 commentaires
Andrei Bobrov
le 6 Jan 2014
Modifié(e) : Andrei Bobrov
le 6 Jan 2014
[a,b] = regexp(num2str(A(:))','(?<=1)2*(?=1)');
t = false(size(A));
for jj = 1:numel(a)
t(a(jj):b(jj)) = true;
end
out = A.*(A==2);
out1=out.*t;
out2 = out.*~t;
or without num2str and regexp
t = [true;diff(A(:))~=0];
n = A(t);
ii = find(t);
m = bsxfun(@plus,strfind(n(:)',[1 2 1]),(1:2)');
tt = false(size(A));
for jj = 1:size(m,2), tt(ii(m(1,jj)):ii(m(2,jj))-1) = true; end
out = A.*(A==2);
out1 = out.*tt;
out2 = out.*~tt;
0 commentaires
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!