Search code examples
matlaboctave

Using the unique function without sorting the values and getting those rows


I'm trying to get all the rows based on the unique values found in the third column and not sort them. see example below. The index of the rows that I would keep would be row 1,2,3,5,7 (in that order) I was thinking of using unique([5 5 3 4],'stable') (the 'stable' option seems to keep the index value order without sorting), but Octave 4.0 which I'm using doesn't have the stable option how can a work around this?

Example array:

C=[
1, 103.4025175681402,    103.4104224840438,    0.007904915903608867;
2, 102.1231938014567,    102.1146017352405,    0.00859206621620956;
3, 97.5338137548381,    97.53996181901071,    0.006148064172606382;
4, 97.54468038366592, 97.53996181901071,    0.004718564655206592;
5, 93.76199482417094,    93.77030145885571,    0.008306634684771552;
6, 93.77539643924416,    93.77030145885571,    0.005094980388449244;
7, 106.976493571217,    106.9837463671074,    0.007252795890309471]

The final array I'm trying to get

D=
[
1, 103.4025175681402,    103.4104224840438,    0.007904915903608867;
2, 102.1231938014567,    102.1146017352405,    0.00859206621620956;
3, 97.5338137548381,    97.53996181901071,    0.006148064172606382;
5, 93.76199482417094,    93.77030145885571,    0.008306634684771552;
7, 106.976493571217,    106.9837463671074,    0.007252795890309471];

Code: I used thanks Brocodile to gives me the index `1,2,4,6,7` I'm trying to get the index `1,2,3,5,7`

C=[1, 103.4025175681402,    103.4104224840438,    0.007904915903608867;
2, 102.1231938014567,    102.1146017352405,    0.00859206621620956;
3, 97.5338137548381,    97.53996181901071,    0.006148064172606382;
4, 97.54468038366592, 97.53996181901071,    0.004718564655206592;
5, 93.76199482417094,    93.77030145885571,    0.008306634684771552;
6, 93.77539643924416,    93.77030145885571,    0.005094980388449244;
7, 106.976493571217,    106.9837463671074,    0.007252795890309471]

[~,i,~] = unique(C(:,3));
D = C(sort(i),:);

output is:

 1       103.40251756814      103.410422484044   0.00790491590360887
 2      102.123193801457       102.11460173524   0.00859206621620956
 4      97.5446803836659      97.5399618190107   0.00471856465520659
 6      93.7753964392442      93.7703014588557   0.00509498038844924
 7      106.976493571217      106.983746367107   0.00725279589030947

Please note this is just an example there will be hundreds of rows. PS: I'm using octave 4.0 on ubuntu 64bit 16.04 Thanks


Solution

  • You can also use unique to get the indices of what is unique by assigning it to multiple variables.

    [D,id,ic] = unique(C);
    

    id here gives us the indices of the unique values that are saved do D in C. If you only want to check the second column for unique values, you can only check the second column with unique(C(:,2)). What you want now are the indices of the unique rows (by column 2) in C; we can get them with [~,i,~] = unique(C(:,2), "first"). In your example this would give us:

        i = 
            5
            3
            2
            1
            7
    

    Now we just need to sort(i) to get the indices in the right order, and then copy the unique rows into D:

    D = C(i,:)
    

    Long story short: You can work around the lack of 'stable' like this:

    [~,i,~] = unique(C(:,2), "first");
    D = C(sort(i),:);