Finding common values in a matrix and create a chain
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
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
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...
Respuesta aceptada
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
Más respuestas (1)
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
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.
Ver también
Categorías
Más información sobre Matrices and Arrays 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!
