Finding common values in a matrix and create a chain
2 views (last 30 days)
Show older comments
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 Comments
dpb
on 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...
Accepted Answer
Ameer Hamza
on 24 Apr 2020
Edited: Ameer Hamza
on 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 Comments
More Answers (1)
dpb
on 24 Apr 2020
Edited: dpb
on 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 Comments
dpb
on 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.
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!