Comment puis-je trier un tableau dans NumPy par la nième colonne?
Par exemple,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Je voudrais trier les lignes par la deuxième colonne, de sorte que je revienne:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
np.sort(a, axis=0)
serait une solution satisfaisante pour la matrice donnée. J'ai suggéré un montage avec un meilleur exemple mais j'ai été rejeté, bien qu'en réalité la question soit beaucoup plus claire. L'exemple devrait ressemblera = numpy.array([[1, 2, 3], [6, 5, 2], [3, 1, 1]])
à la sortie souhaitéearray([[3, 1, 1], [1, 2, 3], [6, 5, 2]])
Réponses:
La réponse de @steve est en fait la manière la plus élégante de le faire.
Pour la manière "correcte", voir l'argument du mot clé order de numpy.ndarray.sort
Cependant, vous devrez voir votre tableau comme un tableau avec des champs (un tableau structuré).
La façon "correcte" est assez moche si vous n'avez pas défini initialement votre tableau avec des champs ...
Comme exemple rapide, pour le trier et renvoyer une copie:
Pour le trier sur place:
@ Steve est vraiment la façon la plus élégante de le faire, autant que je sache ...
Le seul avantage de cette méthode est que l'argument "order" est une liste des champs par lesquels ordonner la recherche. Par exemple, vous pouvez trier par la deuxième colonne, puis la troisième colonne, puis la première colonne en fournissant order = ['f1', 'f2', 'f0'].
la source
ValueError: new type not compatible with array.
float
? Dois-je changer quelque chose?a = np.array([['a',1,2,3],['b',4,5,6],['c',0,0,1]])
quelle approche dois-je suivre?np.argsort
peuvent eux-mêmes occuper beaucoup de mémoire, et en plus, l'indexation avec un tableau générera également une copie du tableau en cours de tri.Je suppose que cela fonctionne:
a[a[:,1].argsort()]
Cela indique la deuxième colonne de
a
et la trie en fonction de celle-ci en conséquence.la source
1
t-il ici? l'index à trier?[:,1]
indique la deuxième colonne dea
.a[a[:,1].argsort()[::-1]]
np.sort
ou non?ind = np.argsort( a[:,1] ); a = a[ind]
Vous pouvez trier sur plusieurs colonnes selon la méthode de Steve Tjoa en utilisant un tri stable comme mergesort et en triant les indices des colonnes les moins significatives aux colonnes les plus significatives:
Cela trie par colonne 0, puis 1, puis 2.
la source
Dans le cas où quelqu'un souhaite utiliser le tri dans une partie critique de ses programmes, voici une comparaison des performances pour les différentes propositions:
Il semble donc que l'indexation avec argsort soit la méthode la plus rapide à ce jour ...
la source
Depuis le wiki de documentation Python , je pense que vous pouvez faire:
La sortie est:
la source
Dans la liste de diffusion NumPy , voici une autre solution:
la source
a[np.lexsort(a.T[cols])]
. oùcols=[1]
dans la question d'origine.J'avais un problème similaire.
Mon problème:
Je veux calculer un SVD et j'ai besoin de trier mes valeurs propres par ordre décroissant. Mais je veux garder la correspondance entre les valeurs propres et les vecteurs propres. Mes valeurs propres étaient dans la première ligne et le vecteur propre correspondant en dessous dans la même colonne.
Je veux donc trier un tableau bidimensionnel par colonne en fonction de la première ligne dans l'ordre décroissant.
Ma solution
Donc comment ça fonctionne?
a[0,]
est juste la première ligne que je veux trier.Maintenant, j'utilise argsort pour obtenir l'ordre des indices.
J'utilise
[::-1]
car j'ai besoin d'un ordre décroissant.Enfin, j'utilise
a[::, ...]
pour obtenir une vue avec les colonnes dans le bon ordre.la source
Un
lexsort
exemple un peu plus compliqué - descendant sur la 1ère colonne, montant secondairement sur la 2ème. Les astuces aveclexsort
sont qu'il trie sur les lignes (d'où le.T
), et donne la priorité au dernier.la source
Voici une autre solution considérant toutes les colonnes (manière plus compacte de la réponse de JJ );
Trier avec lexsort,
Production:
la source
En utilisant simplement le tri, utilisez le numéro de colonne en fonction de celui que vous souhaitez trier.
la source
C'est une vieille question, mais si vous avez besoin de généraliser cela à des tableaux de dimension supérieure à 2, voici la solution qui peut être facilement généralisée:
C'est une exagération pour deux dimensions et
a[a[:,1].argsort()]
serait suffisant selon la réponse de @ steve, mais cette réponse ne peut pas être généralisée à des dimensions plus élevées. Tu peux trouver un exemple de réseau 3D dans cette question.Production:
la source