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