отмена или обратное argsort (), python - PullRequest
15 голосов
/ 20 марта 2010

Учитывая массив '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]

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

Ответы [ 5 ]

35 голосов
/ 23 марта 2010

Вероятно, есть более подходящие решения проблемы, которую вы на самом деле пытаетесь решить, чем эта (выполнение 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])
8 голосов
/ 31 мая 2012

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

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 голосов
/ 20 марта 2010

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

1 голос
/ 26 марта 2017

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

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.

1 голос
/ 20 марта 2010

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

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 была 1-й строкой в ​​исходном массиве, A и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...