Search code examples
matlabreplaceduplicatesfindidentify

Find the indexes of duplicate values and replace their indexes in Matlab


I have a matrix B 1631x5.Download matfile

Columns 2 and 3 represent X and Y coordinates respectively.

I want to identify the indexes where B(i+k,2)==B(i+j,2)&B(i+k,3)==B(i+j,3). Note that there can be more than one duplicate.

Below is the script of identifying the duplicates:

%% X coordinate
[~, indX] = unique(B(:, 2), 'rows');
% duplicate indices
duplicate_indX = setdiff(1:size(B, 1), indX);
% duplicate values
duplicate_valueX = B(duplicate_indX, 2);


%% Y coordinate
[~, indY] = unique(B(:, 3), 'rows');
% duplicate indices
duplicate_indY = setdiff(1:size(B, 1), indY);
% duplicate values
duplicate_valueY = B(duplicate_indY, 3);

%% Both coordinates
duplicate_ind=intersect(duplicate_indX,duplicate_indY);
duplicate_value = B(duplicate_ind, 2:3);

When the code is executed, we get 2 matrix: duplicate_ind(1x149) and duplicate_value(149x2).

Let's consider first 4 values of duplicate_ind as an example:

>> duplicate_ind(1:4)

ans =

    61    77   106   111

The corresponding values for these indexes are

 >> duplicate_value(1:4,:)

ans =

  355.3035  176.9755
  364.7316  182.2644
  354.4987  202.1553
  350.5895  226.7602

Now I can find the original and the duplicate:

find(B(:,2)==duplicate_value(1,1))

ans =

     1
    61

>> find(B(:,2)==duplicate_value(2,1))

ans =

    57
    77

In this case, the index of the original value is 1 and the index of duplicate is 61. In other case: original: 57 and duplicate:77.

Now, I want to replace the indexes of the duplicates by the original ones. In our case 61 will be replaced by 1 (and 77 will be replaced by 57). Considering above, I want to build a matrix which has the size 1631x3 (must have the same number of rows as matrix B), and looks like following:

1   1   2
2   2   3
3   3   4
...
57  57  58
...
61  1   62
...
77  57  78
78  78  79
...

Solution

  • Solved:

    %% X coordinate
    [~, indX] = unique(B(:, 2), 'rows');
    % duplicate indices
    duplicate_indX = setdiff(1:size(B, 1), indX);
    % duplicate values
    duplicate_valueX = B(duplicate_indX, 2);
    
    
    %% Y coordinate
    [~, indY] = unique(B(:, 3), 'rows');
    % duplicate indices
    duplicate_indY = setdiff(1:size(B, 1), indY);
    % duplicate values
    duplicate_valueY = B(duplicate_indY, 3);
    
    %% Both coordinates
    duplicate_ind=intersect(duplicate_indX,duplicate_indY);
    duplicate_value = B(duplicate_ind, 2:3);
    
    indexes=zeros(3,size(duplicate_value,1));
    for i=1:size(duplicate_value,1)
        if size(find(B(:,2)==duplicate_value(i,1)&B(:,3)==duplicate_value(i,2)),1)==2
            indexes(1:2,i)=find(B(:,2)==duplicate_value(i,1)&B(:,3)==duplicate_value(i,2));
        end
        if size(find(B(:,2)==duplicate_value(i,1)&B(:,3)==duplicate_value(i,2)),1)==3
            indexes(1:3,i)=find(B(:,2)==duplicate_value(i,1)&B(:,3)==duplicate_value(i,2));
        end    
    end
    
    for j=1:size(B,1)-1
        lines(j,1:2)=j;
        lines(j,3)=j+1;
    end   
    
    for j=1:size(lines,1)
        for i=1:1:size(indexes,2)
            if indexes(3,i)==0
                if lines(j,2)==indexes(2,i)
                    lines(j,2)=indexes(1,i);
                end
    
                if lines(j,3)==indexes(2,i)
                    lines(j,3)=indexes(1,i);
                end
            end
    
            if indexes(3,i)~=0
                if lines(j,2)==indexes(3,i)
                    lines(j,2)=indexes(1,i);
                end
    
                if lines(j,3)==indexes(3,i)
                    lines(j,3)=indexes(1,i);
                end
    
                if lines(j,2)==indexes(2,i)
                    lines(j,2)=indexes(1,i);
                end
    
                if lines(j,3)==indexes(2,i)
                    lines(j,3)=indexes(1,i);
                end
            end
    
        end
    end