A (possibly compact) way to find (1) unique rows, when rows have switched elements, (2) rows with switched elements, and (3) indices of rows with switched elements
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I have a 2-column matrix and I would need to find the following quantites, possibly in a compact way:
- unique rows, even when the two elements of rows are switched among each other ("u"). With "switched among each other" I mean, for example, that the row ''1 2" is equivalent to the row "2 1".
- rows with switched elements ("s").
- indices of rows with switched elements ("is").
Example:
% input: a 2-column matrix
a = [1 2
4 5
5 1
2 1
1 2
5 2
5 1
1 5
2 9
5 1]
% desired output (1): unique rows
u =
1 2
1 5
2 9
4 5
5 2
% desired output (2): rows with switched elements
s =
1 2 % equivalent to "2 1"
1 5 % equivalent to "5 1"
% desired output (3a): indices in matrix "a" indicating the row "1 2" (equivalent to "2 1")
is(1) =
1
4
5
% desired output (3b): indices in matrix "a" indicating the row "1 5" (equivalent to "5 1")
is(2) =
3
7
8
10
Any suggestions?
Obviously, when the elements of the rows are switched, the unique function does not provide such features (right?):
u = unique(a,'rows')
1 2
1 5
2 1
2 9
4 5
5 1
5 2
4 comentarios
Jan
el 10 de Jun. de 2022
Okay. Thanks for your explanation. It is still unclear to me, why you pick [1 5] and not [5, 1] as result, when the input contains [5, 1; 1, 5], and why [2, 9] appears before [4, 5] in the output.
But this is obviously exactly, what you need. The demands are such specific and some details not mentioned, that I assume no one but you needs this piece of code.
Más respuestas (2)
Mitch Lautigar
el 9 de Jun. de 2022
There isn't a compact way to do this. You will need to build a for loop for each of the conditions you are attempting to do. I've put some code below to help you get started.
%unique rows
a1 = a; %built in for you to compare after the coding is done.
a_temp = []; %this is going to be the "stack" array.
for ii = 1:length(a)
a_temp = [a_temp;sort(a(ii,:))]; Sort all values for each individual row
ends
unique_a = unique(a_temp,'rows'); %gives you the unique rows
%duplicate rows & indices
[x,y] = size(unique_a) %I use this here because this is safer than using length here.
for ii = 1:x %use this for loop to index through the unique array
for jj = 1:length(a_temp) %use this for loop to index through the a_temp array
%the goal for you to do here is to index through the a_temp array finding where the arrays are equivalent.
%the 2 hints i'll give you: You can convert each array to string and use strcmpi(), or take each row from the unique array
%and compare it against all the rows of the a_temp array
end
end
7 comentarios
Jan
el 9 de Jun. de 2022
Replace
a_temp = []; %this is going to be the "stack" array.
for ii = 1:length(a)
a_temp = [a_temp;sort(a(ii,:))]; Sort all values for each individual row
end
by
a_temp = sort(a, 2)
Jan
el 10 de Jun. de 2022
Editada: Jan
el 13 de Jun. de 2022
Although I'm still not sure about the order of outputs, this is how I would solve the problem:
n = size(a, 1);
ua = zeros(size(a));
k = 0;
found = false(n, 1);
match = false(n, 1);
is1 = cell(n, 1);
is2 = cell(n, 1);
s = zeros(size(a));
is = 0;
for ia = 1:n
if ~found(ia)
a1 = a(ia, 1);
a2 = a(ia, 2);
match(:) = false;
switched = false;
for ib = ia + 1:n
if a(ib, 1) == a1 && a(ib, 2) == a2
match(ib) = true;
elseif a(ib, 2) == a1 && a(ib, 1) == a2
match(ib) = true;
if ~switched % [EDITED] collect s: First switched row
is = is + 1;
s(is, 1) = a2;
s(is, 2) = a1;
end
switched = true;
end
end
k = k + 1;
if any(match) % Row exists twice
match(ia) = true; % EDITED: ia added
if switched
ua(k, 1) = min(a1, a2);
ua(k, 2) = max(a1, a2);
is2{k} = find(match)];
else
ua(k, :) = a(ia, :);
is1{k} = find(match);
end
found = found | match; % Already checked, to be ignored later
else % Unique row:
ua(k, 1) = a1;
ua(k, 2) = a2;
end
end
end
ua = ua(1:k, :); % Crop unused output
s = s(1:is, :); % Crop unused output
% Maybe: is1 = is1(~cellfun('isempty', is1));
% Maybe: is2 = is2(~cellfun('isempty', is2));
I assume, this is not a perfect solution for you, but maybe a method to create an altertative approach which is possibly faster.
3 comentarios
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!