web-dev-qa-db-fra.com

Indexer un tableau numpy avec une liste de tuples

Pourquoi ne puis-je pas indexer un ndarray en utilisant une liste d'index Tuple comme ceci?

idx = [(x1, y1), ... (xn, yn)]
X[idx]

Au lieu de cela, je dois faire quelque chose de lourd comme

idx2 = numpy.array(idx)
X[idx2[:, 0], idx2[:, 1]] # or more generally:
X[Tuple(numpy.vsplit(idx2.T, 1)[0])]

Existe-t-il un moyen plus simple, plus pythonique?

13
Emre

Vous pouvez utiliser une liste de tuples, mais la convention est différente de ce que vous voulez. numpy attend une liste d'index de ligne, suivie d'une liste de valeurs de colonne. Vous souhaitez apparemment spécifier une liste de paires (x, y).

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing La section pertinente de la documentation est "index de tableaux entiers".


Voici un exemple, cherchant 3 points dans un tableau 2d. (2 points en 2d peuvent être déroutants):

In [223]: idx
Out[223]: [(0, 1, 1), (2, 3, 0)]
In [224]: X[idx]
Out[224]: array([2, 7, 4])

En utilisant votre style de paires xy d'indices:

In [230]: idx1 = [(0,2),(1,3),(1,0)]
In [231]: [X[i] for i in idx1]
Out[231]: [2, 7, 4]

In [240]: X[Tuple(np.array(idx1).T)]
Out[240]: array([2, 7, 4])

X[Tuple(Zip(*idx1))] est une autre façon de faire la conversion. Tuple() est facultatif dans Python2. Zip(*...) est un idiome Python qui annule l'imbrication d'une liste de listes.

Vous êtes sur la bonne voie avec:

In [242]: idx2=np.array(idx1)
In [243]: X[idx2[:,0], idx2[:,1]]
Out[243]: array([2, 7, 4])

Mon Tuple() est juste un peu plus compact (et pas nécessairement plus 'Pythonic'). Étant donné la convention numpy, une sorte de conversion est nécessaire.

(Faut-il vérifier ce qui fonctionne avec n-dimensions et m-points?)

25
hpaulj

Utilisez des tableaux de tableaux numpy qui peuvent être directement transmis à la matrice pour obtenir les éléments

Index = Tuple(np.array(list(Zip(*index_Tuple))))
new_array = list(prev_array[index])
1
Aarif1430