3

I have a set of data looks like this:

data =

4 35
4 36
4 37
4 39
4 50
6 24
6 35
6 36
6 39
6 50
6 78
10 24
10 35
10 36
10 39
...

The actual matrix is in the order of 70000 X 2. What I want is to form a matrix containing all the unique data pair, so each element is not the same as the previous ones, would be look like

result =

4 35
6 24
10 36

I am think about a method like this
Step 1. find out all the index of unique column 1, in this case would be

index =

1
6
12

Step 2. Do a for-loop like this

result = data(index);

for j = 1:length(index)

  if result(j,2) == result(j-1,2)

     result(j) = data(index+1)

  end

end

Here comes a problem, I have the possibility of getting some result like this

4 35
6 24
10 35

Then it is not unique. However, I don't want to write something like

 if result(j,2) = result(j-1,2) ...
     or result(j,2) = result(j-2,2) ...
     or result(j,2) = result(j-3,2) ...
     or result(j,2) = result(j-4,2) ...
 result(j) = data(index+?)

that would be even more complicated.

Thank you very much for the help in advance.

quinette
  • 31
  • 1
  • 3
  • 2
    Can you explain your result? Why does it contain `[4 35]` and not `[4 36]`? Why does it contain `[10 36]` and not `[10 24]`? – Eitan T Jul 29 '13 at 09:14
  • @Eitan Hello, yes theoretically [4 36] is also the possible solution, but since I sort answer from low to high (column 2), it is like this. And if I got [10 24] the 2nd column will be same as [6 24]. Thanks for asking. – quinette Jul 29 '13 at 12:39

3 Answers3

6

try this:

unique(data,'rows')

C = unique(A,'rows') treats each row of A as a single entity and returns the unique rows of A. The rows of the matrix C are in sorted order. The 'rows' option does not support cell arrays.

Lucius II.
  • 1,832
  • 12
  • 19
0

This should work

I = true(size(data,1),1);
idx = [];
while any(I)
    idx(end+1) = find(I,1,'first');  %#ok
    I = I & all(~bsxfun(@eq, data, data(idx(end),:)),2);
end

result = data(idx,:);
Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
  • hi Mohsen this has the same problem with my for-loop: it select unique value in column 1 but column 2 is still repetitive thanks for help anyway! – quinette Jul 29 '13 at 08:26
  • @quinette I updated the answer. It should consider the second column as well. Note that this approach also works for a matrix with any number of columns. – Mohsen Nosratinia Jul 29 '13 at 08:53
  • hi Mohsen, Thanks a lot for your solution, it works great! Now I need to take some time to understand your code :) – quinette Jul 29 '13 at 09:00
  • hi Mohsen, in fact I do need to apply this on a matrix with more columns now :) Which line of your code involve the considering the 2nd column? I need to change that cuz I don't want to considering my 3rd column. Thanks a lot !!! – quinette Jul 29 '13 at 09:28
  • here the `idx` returns the position of rows that should be chosen. I think the easiest approach is that you create a new matrix with columns that you want to compare and pass it as `data` in this script but in the last row when you are choosing the actual rows use the original matrix. – Mohsen Nosratinia Jul 29 '13 at 09:35
  • @ Mohsen, hello, how could I modify the program if I want to select the rows while the element in column 2 which has no occurrence in column 1 as well? e.g. if the row [24 78] is unique and was selected. However, 24 already appear in a row we selected previously [6 24]. In a word I want element to appear only once regardless of the column, thanks a lot in advance! – quinette Aug 01 '13 at 07:19
  • Hi I just figured out how to do it myself :) Thanks anyway. – quinette Aug 01 '13 at 09:32
0

Hey I just figure out how to do it :) Thank you all for help :)

for j = 1:500 % random number, big enough to find out all my pairs
    k = 1;
    while any(bsxfun(@eq, store, data(k,2))|bsxfun(@eq, store, data(k,1)))
        k = k+1;
       if k > length(data)-1, break, end  

end

    pair(j,:) = data(k,:);
    store(2*j-1) = pair(j,1);
    store(2*j) = pair(j,2);
    fprintf('the loop we are at is %d \n',j);

end
quinette
  • 31
  • 1
  • 3