撤消或反转argsort(),python

Vin*_*ent 20 python arrays sorting numpy

给定一个数组'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)
Run Code Online (Sandbox Code Playgroud)

现在平均每一行

aSortRM = asort.mean(axis=1)
Run Code Online (Sandbox Code Playgroud)

现在用行均值替换行中的每个col.有没有比这更好的方法

aWithMeans = ones_like(a)
for ind in range(r)  # r = number of rows
    aWithMeans[ind]* aSortRM[ind]
Run Code Online (Sandbox Code Playgroud)

现在我需要撤消我在第一步中所做的排序.????

Pau*_*aul 41

对于你实际上试图解决的问题,可能有更好的解决方案(执行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])
Run Code Online (Sandbox Code Playgroud)


小智 9

对于那些仍在寻找答案的人:

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
Run Code Online (Sandbox Code Playgroud)


小智 8

游戏已经很晚了,但是在这里:

import numpy as np
N = 1000 # or any large integer
x = np.random.randn( N )
I = np.argsort( x )
J = np.argsort( I )
print( np.allclose( x[I[J]] , x ) )
>> True
Run Code Online (Sandbox Code Playgroud)

基本上,argsort argsort 因为反向排序的第 n 个元素是 J[n] = k : I[k] = n。也就是说,I[J[n]] = n,因此 J 对 I 进行排序。

  • 这是迄今为止最好的解决方案 (2认同)

Ale*_*lli 5

我不确定如何在中做到最好numpy,但是在纯Python中,推理将是:

aargsort正在range(len(a))告诉您这些项目的aSort来源-很像是在纯Python中:

>>> x = list('ciaobelu')
>>> r = range(len(x))
>>> r.sort(key=x.__getitem__)
>>> r
[2, 4, 0, 5, 1, 6, 3, 7]
>>> 
Run Code Online (Sandbox Code Playgroud)

sorted(x)will 的第一个参数是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']
>>> 
Run Code Online (Sandbox Code Playgroud)

当然,会有更严格,更快速的方式来表达它numpy(不幸的是,我对Python本身的了解不多,我不了解Python本身;-),但是我希望通过展示“您需要执行的操作。