“Desort” a vector (undo a sorting)

♀尐吖头ヾ 提交于 2019-12-23 10:05:36

问题


In Matlab, sort returns both the sorted vector and an index vector showing which vector element has been moved where:

[v, ix] = sort(u);

Here, v is a vector containing all the elements of u, but sorted. ix is a vector showing the original position of each element of v in u. Using Matlab's syntax, u(ix) == v.

My question: How do I obtain u from v and ix?

Of course, I could simply use:

w = zero(size(v));

for i = 1:length(v)
    w(ix(i)) = v(i)
end

if nnz(w == u) == length(u)
    print('Success!');
else
    print('Failed!');
end

But I am having this tip-of-the-tongue feeling that there is a more elegant, single-statement, vectorized way of doing this.


If you are wondering why one would need to do this instead of just using u: I was trying to implement the Benjamini-Hochberg procedure which adjusts each element of the vector based on its position after sorting, but recovering the original order after adjusting was important for me.


回答1:


The solution is:

w(ix) = v;

This is a valid Matlab operation provided that w is either at least as big as v, or not yet declared.

Example:

>> u = [4 8 10 6 2];
>> [v, ix] = sort(u)

    v = 2 4 6 8 10        
    ix = 5 1 4 2 3

>> u(ix)

    ans = 2 4 6 8 10

>> w(ix) = v

    w = 4 8 10 6 2

(Apologies for the trivial question-answer, but I realized the solution as I was typing the question, and thought it might be useful to someone.)



来源:https://stackoverflow.com/questions/13407030/desort-a-vector-undo-a-sorting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!