Argsort 以及Rank的Javascript代码练习
1 引言:argsort以及rank排序问题 $\P$ argsort-定义
假设一个数组$a$由$$\underbrace{[x_0,x_1,\dots,x_i, \dots,x_n]}_{0\dots n乱序}$$构成,那么$b=argsort(a)$定义为:经过排序后a中元素(即$0..n$)的索引数组:
$$ \underbrace{[a中第0大数的索引,\dots,a中第i大数的索引, \dots,a中第n大数的索引]}_{0\dots n} $$
我们假设$a[i]= x$,由于$i是a中第x大的数$,那么$i在b中位置就是x$,${b[x]=i}$,如图所示:
消去x,可得: $$ b[x]=b[a[i]]=i $$
$\S$如果对a进行两次argsort,会发生神魔事情呢,这里由一个文章回答为什么对数列使用两次argsort后能得到原数列的rank数列? - 知乎 (zhihu.com),摘抄如下:
对于一个从0~k-1组成序列a来说,执行argsort得到序列b就是b[a[i]]=i,再执行一次得到c就是c[b[j]]=j,代入j=a[i]得c[b[a[i]]]=a[i],c[i]=a[i],所以一个rank序列两次argsort之后自然会变回原样
结合上面的假设a是一个0…n 乱序而来的数组,那么a里面存储的正好是数组a中各元素的排名。推广到任意乱序的序列S,我们只需要将S里的元素一一映射到$[(S_i,a_i)],a_i\in {0..n}$,然后对$S_i$排序,$argsort.argsort(a)=rank(a)$。
2. Show me the code! // a[i],b[i] = > {...a[i]:b[i]...} zip = function (a, b) { let r = [] for (let i in a) { r.push([a[i], b[i]]) } return r; } // argsort返回的是索引 r,[a[r[0]]..a[r[n]]] 就是将a排序好的数组 function argsort(arr, cmp = (a, b) => a - b) { let arr_ind = zip(arr, range(arr.……