Отменить или отменить 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)

теперь заменяйте каждый col в строке средним числом строк. есть ли лучший способ, чем этот

aWithMeans = ones_like(a)
for ind in range(r)  # r = number of rows
    aWithMeans[ind]* aSortRM[ind]

Теперь мне нужно отменить сортировку, которую я сделал на первом шаге.????

Ответ 1

Я не уверен, как лучше всего это сделать в 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]
>>> 

i., первый аргумент 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;-), но я надеюсь, что это поможет, показывая основной логикой операции "вернуть вещи на место" вам нужно выполнить.

Ответ 2

Есть, вероятно, лучшие решения проблемы, которую вы на самом деле пытаетесь решить, чем это (выполнение 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] # reversed
array([6, 4, 4, 6, 2, 5, 4, 0, 7, 4])

Ответ 3

Для всех, кто все еще ищет ответ:

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

Ответ 4

Я не смог следовать вашему примеру, но более абстрактная проблема - то есть, как отсортировать массив, а затем изменить сортировку - это просто.

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 из A_sorted тривиально, потому что помните, что вы использовали массив индексов ('ndx') для сортировки массива в первую очередь.

# ndx array for example above:  array([6, 9, 8, 0, 1, 2, 4, 7, 3, 5])

Другими словами, 4-я строка в A_sorted была первой строкой в ​​исходном массиве, A и т.д.

Ответ 5

Супер поздно к игре, но здесь:

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: я [k] = n. То есть я [J [n]] = n, поэтому J сортирует I.