问题
I have a matrix
[1 2
3 6
7 1
2 1]
and would like to remove mirror imaged pairs..i.e. output would be either:
[1 2
3 6
7 1]
or
[3 6
7 1
2 1]
Is there a simple way to do this? I can imagine a complicated for loop, something like (or a version which wouldn't delete the original pair..only the duplicates):
for i=1:y
var1=(i,1);
var2=(i,2);
for i=1:y
if array(i,1)==var1 && array(i,2)==var2 | array(i,1)==var2 && array(i,2)==var1
array(i,1:2)=[];
end
end
end
thanks
回答1:
How's this for simplicity -
A(~any(tril(squeeze(all(bsxfun(@eq,A,permute(fliplr(A),[3 2 1])),2))),2),:)
Playing code-golf? Well, here we go -
A(~any(tril(pdist2(A,fliplr(A))==0),2),:)
If dealing with two column matrices only, here's a simpler version of bsxfun
-
M = bsxfun(@eq,A(:,1).',A(:,2)); %//'
out = A(~any(tril(M & M.'),2),:)
Sample run -
A =
1 2
3 6
7 1
6 5
6 3
2 1
3 4
>> A(~any(tril(squeeze(all(bsxfun(@eq,A,permute(fliplr(A),[3 2 1])),2))),2),:)
ans =
1 2
3 6
7 1
6 5
3 4
>> A(~any(tril(pdist2(A,fliplr(A))==0),2),:)
ans =
1 2
3 6
7 1
6 5
3 4
回答2:
Here a not so fancy, but hopefully understandable and easy way.
% Example matrix
m = [1 2; 3 6 ; 7 1; 2 1; 0 3 ; 3 0];
Comparing m with its flipped version, the function ismember
returns mirror_idx
, a 1D-vector with each row containing the index of the mirror-row, or 0 if there's none.
[~, mirror_idx] = ismember(m,fliplr(m),'rows');
Go through the indices of the mirror-rows. If you find one "mirrored" row (mirror_idx > 0
), set its counter-part to "not mirrored".
for ii = 1:length(mirror_idx)
if (mirror_idx(ii) > 0)
mirror_idx(mirror_idx(ii)) = 0;
end
end
Take only the rows that are marked as not having a mirror.
m_new = m(~mirror_idx,:);
Greetings
来源:https://stackoverflow.com/questions/34909847/matlab-detect-and-remove-mirror-imaged-pairs-in-2-column-matrix