一步实现方法: [~, ~, idx] = unique(a, 'sorted'); 但这种方法无法实现逆序。

如果想实现逆序必须通过两步才能实现:

[~, idx] = sort(a, 'ascend');         [~, idx] = sort(idx, 'ascend') %其中`ascend`可省略或者:

[~, idx] = sort(a, 'ascend');           [~, ~, idx] = intersect(1:length(idx), idx);或者:

[~, idx] = sort(a, 'ascend');         idx(idx) = 1:length(idx);能够这么写的原因:对于a = [7 5 9 3 10] 来说,一步sort返回的idx表示的是排名分为为1、2、3、4、5位的数在原始序列中的位置。而我们想要的是原始序列中位置为1、2、3、4、5的数他们在排序后序列中的位置。一步sort得到的idx是[4 2 1 3 5],表示的是按照大小排名12345位(记为C)的数字在原始序列中的位置序号分别是42135(记为B),这个B和C有个反向对应关系,B一一对应到C就是原始位置上各数字的排序秩了(就是上述2中的第三种方法,理解起来最简单)。

要理解第一种和第二种的做法,需要知道,12345这列数字有两层含义:一表示从小到大排序的顺序值,二表示原始数据从左到右的位置值,因为这两项含义体现出来的数字都是12345,所以上述两种方法应用中用到了这一转化。

比如intersect的方法,最后落脚在找到12345在42135中的位置,这里前一个12345表示的是原始数据从左到右的位置值,在42135中的位置表示的是排序,12345中的1表示原始序列中的第一个数(7),它在42135中的位置是3,表示7在原始序列中排名第3(因为42135就是按照大小顺序排出来的),这里有点绕,但是仔细想想还是能明白。

第一种两种sort的方法也是12345的双重含义转化,一步sort得到的42135表示排名12345位的数据在原始数列中的位置,这是排名12345其实就是打乱顺序的秩:

7 5 9 3 10 原始数列

3 5 7 9 10 排序后的新数列

4 2 1 3 5 排序后新数列每个数在原始数列中的位置(A)

1 2 3 4 5 排序后新数列的大小顺序(B)

A到B的转化,以1 3 这组为例,A中1表示原始数列的index,B中的3表示index为3的原数值(7)排序是3。这里sort(A)就是42135这组数排序后每个数(12345,既是排序后的新数列,又是从左向右的index)在42135中的位置,也就是原始数据的大小顺序,也是有点绕。。

不管怎样,几种方法都能实现目标,虽然每个就多写一句,但是感觉还是不如一个rank函数来的简洁,而且理解起来很绕,在此记录下来,以后回看不要被绕晕。当然回看的时候如果觉得很简单,当时很傻*就更好了,说明成长很快哈哈~