Numpy: argsort dá resultados errados

Criado em 8 mar. 2017  ·  4Comentários  ·  Fonte: numpy/numpy

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]])
53 - Invalid

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:

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]

Todos 4 comentários

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))

9880 sugere adicionar isso ao numpy como 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.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Kreol64 picture Kreol64  ·  3Comentários

dmvianna picture dmvianna  ·  4Comentários

MareinK picture MareinK  ·  3Comentários

inducer picture inducer  ·  3Comentários

keithbriggs picture keithbriggs  ·  3Comentários