Finding common values in a matrix and create a chain
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Armindo Barbosa
am 24 Apr. 2020
Kommentiert: dpb
am 25 Apr. 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 Kommentare
dpb
am 24 Apr. 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...
Akzeptierte Antwort
Ameer Hamza
am 24 Apr. 2020
Bearbeitet: Ameer Hamza
am 25 Apr. 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 Kommentare
Weitere Antworten (1)
dpb
am 24 Apr. 2020
Bearbeitet: dpb
am 25 Apr. 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 Kommentare
dpb
am 25 Apr. 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.
Siehe auch
Kategorien
Mehr zu Matrices and Arrays finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
