A função argsort parece estar quebrada. Olhando para o código fornecido, o argsort para as linhas [0, 1] está correto, mas está confuso para as linhas [2, 3].
Eu testei isso em diferentes instalações do NumPy e versões 1.11.0 e 1.12.0
import numpy as np
vec = np.array([
[-1.4, -1.2, 1.3],
[-3.6, 3.9, -3.7],
[-2.3, 1.5, -2. ],
[-2.6, 2.4, -1.6]
])
In [1]: np.argsort(-vec, axis=1)
Out[1]:
array([[2, 1, 0],
[1, 0, 2],
[1, 2, 0],
[1, 2, 0]])
Não consegue ver nada de errado com o resultado, imprima vec[np.arange(4)[:, np.newaxis], np.argsort(-vec, axis=1)]
e veja se ficou bom.
Este é o segundo resultado do Google para "np argsort errado".
A explicação na página de documentos não é clara (para mim). Vou adicionar minha própria explicação aqui na esperança de que ajude alguém:
x = numpy.array([1.48,1.31,0.0,0.8])
print x.argsort()
>[2 3 1 0]
Algumas pessoas podem esperar que isso dê [3, 2, 0, 1]
, ou seja, o 0º elemento no array não ordenado deve ser o 3º elemento no array ordenado.
O que ele realmente faz é fornecer índices tais que x[np.argsort(x)]
lhe dará uma lista ordenada, ou seja, [0.0, 0.8, 1.31, 1.48]
. Dito de outra forma, [2 3 1 0]
informa que o 0º elemento do array ordenado é o 2º elemento do array não ordenado.
Se você realmente deseja obter [3, 2, 0, 1]
como saída, pode fazer
np.argsort(np.argsort(x))
>[3 2 0 1]
Alternativamente, se você está realmente fora da base como eu estava e só quer, digamos, os índices dos 3 maiores elementos em x
:
np.argsort(x)[:-4:-1]
>[0, 1, 3]
Se você realmente deseja obter [3, 2, 0, 1] como saída, pode fazer
Fazer isso será mais rápido:
a = np.empty(len(x), np.intp)
a[np.argsort(x)] = np.arange(len(x))
np.invert_permutation(np.argsort(x))
@rossbar , @bjnath : Talvez valha a pena extrair coisas do comentário do @ghost acima e colocá-las nos documentos? Adicionei mais links cruzados para mostrar mais exemplos de confusão.
Comentários muito úteis
Este é o segundo resultado do Google para "np argsort errado".
A explicação na página de documentos não é clara (para mim). Vou adicionar minha própria explicação aqui na esperança de que ajude alguém:
Algumas pessoas podem esperar que isso dê
[3, 2, 0, 1]
, ou seja, o 0º elemento no array não ordenado deve ser o 3º elemento no array ordenado.O que ele realmente faz é fornecer índices tais que
x[np.argsort(x)]
lhe dará uma lista ordenada, ou seja,[0.0, 0.8, 1.31, 1.48]
. Dito de outra forma,[2 3 1 0]
informa que o 0º elemento do array ordenado é o 2º elemento do array não ordenado.Se você realmente deseja obter
[3, 2, 0, 1]
como saída, pode fazerAlternativamente, se você está realmente fora da base como eu estava e só quer, digamos, os índices dos 3 maiores elementos em
x
: