Finding common values in a matrix and create a chain

1 visualización (últimos 30 días)
Armindo Barbosa
Armindo Barbosa el 24 de Abr. de 2020
Comentada: dpb el 25 de Abr. de 2020
I have a A matrix 8124x4 and I want to save in a different matrix B all the rows that have the same value in a single element (could be different columns), the values dont have any type of relation in the A matrix.
Example:
,taking this as an example for a smaller A matrix, I wanna save the 1st row in B, then the 4th row also because it has a "12" in it, then the second row should also be saved in B because it has a "10" (like the second row).
  4 comentarios
dpb
dpb el 24 de Abr. de 2020
Figured, just checkin'...
BTW, for future, don't post images of data; paste the text so folks can just cut 'n paste for testing. Formatting as code is best...

Iniciar sesión para comentar.

Respuesta aceptada

Ameer Hamza
Ameer Hamza el 24 de Abr. de 2020
Editada: Ameer Hamza el 25 de Abr. de 2020
Try something like this
A = [1 9 12 17; 2 3 90 10; 3 32 55 22; 4 12 2 10; 13 30 40 70; 89 101 90 98; 7 55 200 300; 10 39 29 122; 13 219 100 122; 1000 3233 4003 1220; 8328 12 32 124];
B_counter = 1;
B{B_counter}(1, :) = A(1, :);
last_rows = A(1, :);
A(1, :) = [];
count = 2;
for i=1:size(A,1)
[r, ~] = find(ismember(A(:, 2:end), last_rows(:, 2:end)));
if isempty(A)
break;
elseif isempty(r)
B_counter = B_counter + 1;
B{B_counter}(1, :) = A(1, :);
last_rows = A(1, :);
A(1, :) = [];
count = 2;
else
B{B_counter}(count:count+numel(r)-1, :) = A(r, :);
last_rows = A(r, :);
A(r, :) = [];
count = count+numel(r);
end
end
B = cellfun(@(b) {unique(b, 'rows', 'stable')}, B);
  24 comentarios
Ameer Hamza
Ameer Hamza el 25 de Abr. de 2020
Glad to be of help.

Iniciar sesión para comentar.

Más respuestas (1)

dpb
dpb el 24 de Abr. de 2020
Editada: dpb el 25 de Abr. de 2020
Same idea, different cat skinned to get there...
u=unique(A(:,2:end)); % look for these values' places in A
ix=arrayfun(@(u) find(A(:,2:end)==u),u,'UniformOutput',false); % linear index in array
ix=ix(cellfun(@(r) length(r)>1,ix)); % keep only >1 match
[r,~]=cellfun(@(i) ind2sub(size(A(:,2:end)),i),ix,'uni',0); % back to r,c subscripts
r=unique(vertcat(r{:})); % only use row once
B=A(r,:) % those rows whole array
% with your A(:,2:end) results in
>> B
B =
9 12 17
3 90 10
12 2 10
>>
I just kept the data portion of the array, you can change references to A to A(:,2:end).
Also NB: the second output argument from ind2sub MUST be present even though are throwing it away...otherwise just returns the linear index again instead of the row.
ADDENDUM:
For your addended array above above yields
>> B
B =
1 9 12 17
2 3 90 10
3 32 55 22
4 12 2 10
89 101 90 98
7 55 200 300
10 39 29 122
13 219 100 122
8328 12 32 124
>> sortrows(B,1)
ans =
1 9 12 17
2 3 90 10
3 32 55 22
4 12 2 10
7 55 200 300
10 39 29 122
13 219 100 122
89 101 90 98
8328 12 32 124
>>
What's not to like given initial description of wanted result?
  4 comentarios
Armindo Barbosa
Armindo Barbosa el 25 de Abr. de 2020
the B matrix appears equal to the A in the end
dpb
dpb el 25 de Abr. de 2020
Only if all lines have duplicates or there are values duplicated across each line.
The result for your sample array is
>> whos A B
Name Size Bytes Class Attributes
A 11x4 352 double
B 9x4 288 double
>>
so two lines didn't have duplicates in other line. Visual inspection confirms there are no row in B that are unique in all three data elements.

Iniciar sesión para comentar.

Categorías

Más información sobre Matrices and Arrays en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by