给定一个数组'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)
现在用行均值替换行中的每个col。 有没有比这更好的方法
aWithMeans = ones_like(a)
for ind in range(r) # r = number of rows
aWithMeans[ind]* aSortRM[ind]
现在我需要撤消我在第一步中所做的排序。 ????
答案 0 :(得分:35)
对于您实际尝试解决的问题,可能有更好的解决方案(执行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])
答案 1 :(得分:7)
对于那些仍在寻找答案的人:
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
答案 2 :(得分:4)
我不确定如何在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]
>>>
即,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本身一样;-)但我希望这有助于通过展示你需要执行的“把东西放回原处”操作的基本逻辑。
答案 3 :(得分:2)
indices=np.argsort(a)
为您提供排序索引,例如x = a[indices]
为排序数组。 y = b[indices]
将数组b
前移到已排序的域。 c[indices] = z
将z
从已排序的域拉回到源域中的c
。
例如,
import numpy as np
n = 3
a = np.random.randint(0,10,n) # [1, 5, 2]
b = np.random.randn(n) # [-.1, .5, .2]
c = np.empty_like(a)
# indices that sort a: x=a[indices], x==np.sort(a) is all True
indices = np.argsort(a) # [0,2,1]
# y[i] is the value in b at the index of the i-th smallest value in a
y = b[indices] # [-.1, .2, .5]
# say z[i] is some value related to the i-th smallest entry in a
z = np.random.randn(n) # [-1.1, 1.2, 1.3]
c[indices] = z # inverted the sorting map, c = [-1.1, 1.3, 1.2]
答案 4 :(得分:1)
我无法按照你的例子,但更抽象的问题 - 即,如何对数组进行排序然后反转排序 - 很简单。
import numpy as NP
# create an 10x6 array to work with
A = NP.random.randint(10, 99, 60).reshape(10, 6)
# for example, sort this array on the second-to-last column,
# breaking ties using the second column (numpy requires keys in
# "reverse" order for some reason)
keys = (A[:,1], A[:,4])
ndx = NP.lexsort(keys, axis=0)
A_sorted = NP.take(A, ndx, axis=0)
从A_sorted“重建”A是微不足道的,因为请记住您首先使用索引数组('ndx')对数组进行排序。
# ndx array for example above: array([6, 9, 8, 0, 1, 2, 4, 7, 3, 5])
换句话说,A_sorted中的第4行是原始数组中的第1行,A等。
答案 5 :(得分:1)
比赛已经很晚了,但是在这里:
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
基本上,argsort是argsort,因为反向排序的第n个元素是J [n] = k:I [k] = n。也就是说,我[J [n]] = n,所以J对I.进行排序。