撤销或反转argsort(),python
给定一个数组'a',我想按列对这个数组进行排序,使用sort(a, axis=0)
。然后对数组做一些处理,最后再把排序的结果撤销。这里的撤销不是重新排序,而是基本上要把每个元素的移动方式反过来。我想argsort()
是我需要的,但我不太清楚如何用argsort()
的结果来排序数组,或者更重要的是,如何应用argsort()
的反向操作。
这里有更多的细节
我有一个数组a
,shape(a) = rXc
,我需要对每一列进行排序。
aargsort = a.argsort(axis=0) # May use this later
aSort = a.sort(axis=0)
然后计算每一行的平均值。
aSortRM = asort.mean(axis=1)
接着用每行的平均值替换该行中的每一列。有没有比这个更好的方法呢?
aWithMeans = ones_like(a)
for ind in range(r) # r = number of rows
aWithMeans[ind]* aSortRM[ind]
现在我需要撤销第一步中做的排序。????
7 个回答
12
对于那些仍在寻找答案的人:
In [135]: r = rand(10)
In [136]: i = argsort(r)
In [137]: r_sorted = r[i]
In [138]: i_rev = zeros(10, dtype=int)
In [139]: i_rev[i] = arange(10)
In [140]: allclose(r, r_sorted[i_rev])
Out[140]: True
83
你可能有更好的方法来解决你真正想解决的问题,而不是这个(通常执行 argsort 的时候其实不需要真的去排序),不过我还是给你提供这个:
>>> import numpy as np
>>> a = np.random.randint(0,10,10)
>>> aa = np.argsort(a)
>>> aaa = np.argsort(aa)
>>> a # original
array([6, 4, 4, 6, 2, 5, 4, 0, 7, 4])
>>> a[aa] # sorted
array([0, 2, 4, 4, 4, 4, 5, 6, 6, 7])
>>> a[aa][aaa] # undone
array([6, 4, 4, 6, 2, 5, 4, 0, 7, 4])
9
我不太确定在 numpy
中怎么做最好,但在纯 Python 中,思路是这样的:
aargsort
里保存的是一个排列,表示 aSort
中的元素最初来自哪里——就像在纯 Python 中:
>>> x = list('ciaobelu')
>>> r = range(len(x))
>>> r.sort(key=x.__getitem__)
>>> r
[2, 4, 0, 5, 1, 6, 3, 7]
>>>
也就是说,sorted(x)
的第一个参数会是 x[2]
,第二个是 x[4]
,依此类推。
所以,给定排序后的版本,你可以通过“把元素放回它们原来的地方”来重建原始数据:
>>> s = sorted(x)
>>> s
['a', 'b', 'c', 'e', 'i', 'l', 'o', 'u']
>>> original = [None] * len(s)
>>> for i, c in zip(r, s): original[i] = c
...
>>> original
['c', 'i', 'a', 'o', 'b', 'e', 'l', 'u']
>>>
当然,在 numpy
中会有更紧凑和更快的方法来表达这个过程(不过我对它的了解没有对 Python 本身那么深入;-),但我希望这能通过展示“把东西放回原位”的基本逻辑来帮助你理解你需要执行的操作。