# Collect double values of a matrix

6 views (last 30 days)
Tobias Riewendt on 7 Oct 2019
Commented: Tobias Riewendt on 9 Oct 2019
Hi,
I have got a question. I have a matrix with three columns (X,Y,Z coordinates) and nearly 60000 rows. Now, I would like to compare the X and Z values of all 60000 rows. All rows whose X and Z values only occur once should be deleted, only the rows whose X and Z value occur twice or more should be regarded. Next, the rows with the equal X and Z value should be compared and the row with the higher Y value should be written into a new matrix.
I thought about using a loop for the search of the rows with equal X and Z values but the computing time is quite high, is there a better way? And how do I define the "do"?
for k = 1:end
for m = k+1:end
if A(k,1) == A(m,1) && A(k,3) ==A(m,3)
do something
end
end
end
I haven't thought about the loop for the search of the higher Y value, yet.
Yours,
Tobias

Andrei Bobrov on 9 Oct 2019
Edited: Andrei Bobrov on 9 Oct 2019
Let xyz - your array (n x 3);
[~,~,c] = unique(xyz(:,[1,3]),'rows','stable'); % c - serial numbers of rows with same values in first and last columns.
d = accumarray(c,1); % d - the number of specific rows with the same first and last columns. Here first row of 'd' c = 1, nth row - c = n.
[lo,i] = ismember(c,find(d > 1)); % duplicate rows in xyz.
j = accumarray(i(lo),find(lo),[],@(x)x(max(xyz(x,2)) == xyz(x,2))); % index of the row with the maximum value in the second column.
out = xyz(j,:);
Tobias Riewendt on 9 Oct 2019

Martin C. on 8 Oct 2019
hmm well to count occurences you could somehow use a hashmap
containers.Map in matlab. that would be efficient.

Turlough Hughes on 8 Oct 2019
Edited: Turlough Hughes on 9 Oct 2019
I would first find rows which have equal X and Z values.
c=1;
for ii=1:size(A,1)
if A(ii,1)==A(ii,3)
id_s(c)=ii;
c=c+1;
end
end
B=A(id_s,:);
Rows in A with equal X and Z value and are assigned to B.
To ensure a given X (and hence a given Z) of a row is repeated in another row I find the rows where this is not the case and delete them.
[~,ix] = unique(B(:,1)); % so B(ix,1) includes all values in B(:,1) without repeating any.
Xtw=B(:,1);
Xtw(ix)=[]; % Xtw - includes all values in X that occurred two or more times.
[~,i1x]=setdiff(B(:,1),Xtw); % Gets index for rows in B where the x value is not repeated elsewhere.
B(i1x,:)=[];
Tobias Riewendt on 9 Oct 2019
That is not exactly what I want. I try to give an example:
[X , Y , Z]:
[1 2 3
2 5 3
7 7 7
7 7 9
1 5 3]
The result should be a matrix of the rows with an equal X AND Z value. All other rows should be deleted. This means:
[1 2 3
1 5 3]