Como posso classificar uma matriz no NumPy pela enésima coluna?
Por exemplo,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Gostaria de classificar as linhas pela segunda coluna, para que eu volte:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
np.sort(a, axis=0)
seria uma solução satisfatória para a matriz especificada. Sugeri uma edição com um exemplo melhor, mas fui rejeitada, embora, na verdade, a questão seja muito mais clara. O exemplo deve ser algo comoa = numpy.array([[1, 2, 3], [6, 5, 2], [3, 1, 1]])
com saída desejadaarray([[3, 1, 1], [1, 2, 3], [6, 5, 2]])
Respostas:
A resposta de @steve é realmente a maneira mais elegante de fazer isso.
Para a maneira "correta", consulte o argumento da palavra-chave da ordem numpy.ndarray.sort
No entanto, você precisará visualizar sua matriz como uma matriz com campos (uma matriz estruturada).
A maneira "correta" é muito feia se você não definiu inicialmente sua matriz com campos ...
Como um exemplo rápido, para classificá-lo e retornar uma cópia:
Para classificá-lo no local:
@ Steve realmente é a maneira mais elegante de fazê-lo, tanto quanto eu sei ...
A única vantagem desse método é que o argumento "order" é uma lista dos campos para ordenar a pesquisa. Por exemplo, você pode classificar pela segunda coluna, depois pela terceira coluna e depois pela primeira coluna, fornecendo a ordem = ['f1', 'f2', 'f0'].
fonte
ValueError: new type not compatible with array.
float
? Devo mudar alguma coisa?a = np.array([['a',1,2,3],['b',4,5,6],['c',0,0,1]])
qual abordagem devo seguir?np.argsort
themselve pode levar até um monte de memória, e em cima disso, a indexação com uma matriz também irá gerar uma cópia da matriz que está sendo classificada.Suponho que isso funcione:
a[a[:,1].argsort()]
Isso indica a segunda coluna de
a
e classifica-a com base nela de acordo.fonte
1
aqui? o índice a ser classificado por?[:,1]
indica a segunda coluna dea
.a[a[:,1].argsort()[::-1]]
np.sort
ou não?ind = np.argsort( a[:,1] ); a = a[ind]
Você pode classificar em várias colunas, de acordo com o método de Steve Tjoa, usando uma classificação estável como mergesort e classificando os índices das colunas menos significativas para as mais significativas:
Classifica pela coluna 0, depois 1 e 2.
fonte
A partir da documentação wiki Python , eu acho que você pode fazer:
A saída é:
fonte
Caso alguém queira fazer uso da classificação em uma parte crítica de seus programas, aqui está uma comparação de desempenho para as diferentes propostas:
Portanto, parece que a indexação com argsort é o método mais rápido até agora ...
fonte
Na lista de discussão do NumPy , aqui está outra solução:
fonte
a[np.lexsort(a.T[cols])]
. ondecols=[1]
na pergunta original.Eu tive um problema parecido.
Meu problema:
Quero calcular um SVD e preciso classificar meus valores próprios em ordem decrescente. Mas quero manter o mapeamento entre valores próprios e vetores próprios. Meus autovalores estavam na primeira linha e o vetor próprio correspondente abaixo dele na mesma coluna.
Então, eu quero classificar uma matriz bidimensional em colunas pela primeira linha em ordem decrescente.
Minha solução
Então, como isso funciona?
a[0,]
é apenas a primeira linha pela qual quero classificar.Agora eu uso o argsort para obter a ordem dos índices.
Eu uso
[::-1]
porque preciso de ordem decrescente.Por fim, eu uso
a[::, ...]
para obter uma exibição com as colunas na ordem correta.fonte
Um
lexsort
exemplo um pouco mais complicado - descendo na 1ª coluna, subindo secundariamente na 2ª. Os truqueslexsort
são que ele classifica em linhas (daí o.T
), e dá prioridade ao último.fonte
Aqui está outra solução considerando todas as colunas (maneira mais compacta da resposta de JJ );
Classifique com lexsort,
Resultado:
fonte
Simplesmente usando a classificação, use o número da coluna com base no qual você deseja classificar.
fonte
É uma pergunta antiga, mas se você precisar generalizar isso para matrizes de mais de duas dimensões, aqui está a solução que pode ser facilmente generalizada:
Isso é um exagero para duas dimensões e
a[a[:,1].argsort()]
seria suficiente por resposta de @ steve, no entanto, essa resposta não pode ser generalizada para dimensões superiores. Você pode encontrar um exemplo de matriz 3D nesta pergunta.Resultado:
fonte