2014-09-19 2 views
2

Je voudrais écrire une routine, qui lit les valeurs de certains éléments d'un tableau. La sélection d'élément est spécifiée sous la forme d'un tableau, où chaque ligne contient les indices d'un élément. La routine devrait fonctionner pour les tableaux avec un nombre arbitraire d'axes.Lire des éléments avec des indices donnés à partir d'un tableau avec un nombre arbitraire d'axes

Je pourrais trouver la solution ci-dessous, mais je ne l'aime pas, car la conversion en tuple (ou liste) semble en quelque sorte inutile, bien que j'en ai besoin pour empêcher l'indexation avancée. Y a-t-il un moyen plus numpythonique de faire ça?

import numpy as np 

def get_elements(aa, inds): 
    myinds = tuple(inds.transpose()) 
    return aa[myinds] 

AA = np.arange(6) 
AA.shape = (3, 2) 
inds = np.array([[ 0, 0 ], [ 2, 1 ]]) 
data2 = get_elements(AA, inds) # contains [ AA[0,0], A[2,1] ] 

BB = np.arange(12) 
BB.shape = (2, 3, 2) 
inds = np.array([[ 0, 0, 0], [ 1, 2, 1 ]]) 
data3 = get_elements(BB, inds) # contains [ BB[0,0,0], BB[1,2,1] ] 
+2

Pour ce que ça vaut, la conversion en tuple n'est pas trop inefficace ici. Il crée un tuple de vues de 'inds', donc il n'y a pas de copies faites (juste de nouveaux objets python qui font référence à la même mémoire). Il y a une autre façon de faire cela, mais c'est beaucoup plus rond (combiner 'np.take' et' np.ravel_multi_index', par exemple 'b.take (np.ravel_multi_index (inds.T, b.shape))'). –

+0

Beaucoup de fonctions de 'numpy' font juste cela - prendre des nombres d'index ou d'axe, et générer un index de tuple à partir de cela. – hpaulj

+0

OK, je vois, merci. En effet la fonction ravel_multi_index() serait aussi une option à laquelle je n'ai pas pensé. –

Répondre

1

Votre tuple(ind.T) produit la même chose que np.where pour les mêmes éléments.

In [117]: AA=np.arange(6).reshape(3,2) 
In [118]: ind=np.array([[0,0],[2,1]]) 
In [119]: tuple(ind.T) 
Out[119]: (array([0, 2]), array([0, 1])) 
In [120]: AA[tuple(ind.T)] 
Out[120]: array([0, 5]) 

En utilisant where pour trouver les indices de ces 2 valeurs:

In [121]: np.where((AA==0) + (AA==5)) 
Out[121]: (array([0, 2]), array([0, 1])) 

et la copie de la doc pour where, une autre façon de trouver les [0,5] valeurs:

In [125]: np.in1d(AA.ravel(), [0,5]).reshape(AA.shape) 
Out[125]: 
array([[ True, False], 
     [False, False], 
     [False, True]], dtype=bool) 
In [126]: np.where(np.in1d(AA.ravel(), [0,5]).reshape(AA.shape)) 
Out[126]: (array([0, 2]), array([0, 1])) 

Ainsi, votre tuple est parfaitement bon code numpy.

De numpy documents d'indexation:

Remarque En Python, x [(exp1, exp2, ..., expN)] est équivalent à x [exp1, exp2, ..., EXPN]; ce dernier n'est que du sucre syntaxique pour le premier.

+0

+1 seulement une remarque que la partie de sucre syntaxique est valide pour l'indexation de fantaisie avec des tableaux NumPy ... –

Questions connexes