2010-01-06 6 views
0

Cela fonctionne très bien dans 1 dimension:indices Sélection pour un tableau 2d numpy

# This will sort bar by the order of the values in foo 
(Pdb) bar = np.array([1,2,3]) 
(Pdb) foo = np.array([5,4,6]) 
(Pdb) bar[np.argsort(foo)] 
array([2, 1, 3]) 

Mais comment puis-je faire cela en deux dimensions? Argsort fonctionne très bien, mais la sélection ne fonctionne plus:

(Pdb) foo = np.array([[5,4,6], [9,8,7]]) 
(Pdb) bar = np.array([[1,2,3], [1,2,3]]) 
(Pdb) bar[np.argsort(foo)] 
*** IndexError: index (2) out of range (0<=index<=1) in dimension 0 
(Pdb) 

je me attends à ce à la sortie:

array([[2, 1, 3], [3, 2, 1]]) 

Toute idée de comment le faire?

Merci! /YGA

Modifier: take() semblerait faire la bonne chose, mais il ne prend vraiment que des éléments de la première rangée (super confus).

Vous pouvez voir que si je change les valeurs de la barre:

(Pdb) bar = np.array([["1","2","3"], ["A", "B", "C"]]) 
(Pdb) bar.take(np.argsort(foo)) 
array([['2', '1', '3'], 
     ['3', '2', '1']], 
     dtype='|S1') 
(Pdb) 
+0

'bar [[[0], [1]], np.argsort (foo)]' semble fais ce que tu veux, cependant. –

+0

@Alok: oui, mais la stratégie semblait échouer sur un exemple plus compliqué (je dois aussi dire que je le trouve un peu énigmatique). – YGA

+0

@YGA: Pouvez-vous nous dire quel est l'exemple compliqué? Je vais vous expliquer la méthode plus en détail plus tard aujourd'hui, si vous le souhaitez. –

Répondre

0

bar.take(np.argsort(foo)) produit votre sortie désirée, vous devriez jeter un oeil à son documentation pour vous assurer qu'il ne fait ce que vous pensez que vous voulez.

Edit:

Essayez ceci: bar.take(np.argsort(foo.ravel()).reshape(foo.shape))

+0

(essayé d'ajouter un commentaire, mais il a été mal formaté parce que vous ne pouvez pas avoir de code dans les commentaires.) Voir – YGA

+0

Droite vous êtes - il prend basé sur les dimensions aplaties, et 0, 1 et 2 tous se trouvent dans le première rangée de ce tableau. Ici, cela pourrait fonctionner ... – kwatford

+0

Très sympa! Merci! – YGA

2

Vous voulez

bar[[[0],[1]], np.argsort(foo)] 

Ceci est parce que vous avez besoin de deux indices pour indexer bar. Le [[0], [1]] consiste à obtenir une diffusion correcte. Voir la liste de diffusion this post on numpy-discussion pour exactement la même question et la réponse.

1

Une solution générique agréable (avec n lignes à trier) est offert at this post, à savoir,

bar[np.arange(foo.shape[0])[:,None], np.argsort(foo)]