1
votes

Indexer le tableau numpy par un autre tableau en tant qu'indices

J'essaye de prendre le tableau

c = [a[b[0], a[b[1], ...]

et le tableau

b = [(2,3), (5,4), (1,2), (1,0)]

Et je veux que b soit les index de a, par exemple un nouveau tableau qui est

[a[b[0]], a[b[1]], a[b[2]], a[b[3]] ...]

Les valeurs de b sont donc des index dans a. Et il y a 500k entrées dans a et 500k dans b (environ). Existe-t-il un moyen rapide de lancer tous les cœurs dans numpy pour ce faire? Je le fais déjà très bien dans les boucles for et c'est sloooooooowwwwww.

Modifiez pour clarifier. La solution doit fonctionner pour les tableaux 2D et 3D. alors peut-être

b = [3,5,6,2,7]

et nous voulons

a = [1,5,4,5,7,8,9,8,4,13,43,42]


0 commentaires

3 Réponses :


2
votes

Je ne dis pas que c'est rapide, mais le moyen le plus simple serait simplement:

a[b]

sorties:

tableau ([5, 8, 9, 4, 8])


1 commentaires

Réponse élégante!



2
votes

Cela peut être fait dans NumPy en utilisant indexation avancée . Comme l'a souligné la réponse de Christian , dans le cas 1-D, vous écririez simplement:

print(np.take(a, b))

et cela équivaut à:

b0, b1, b2 = zip(*b)
print(a[b0, b1, b2])

Dans les cas de plus grande dimension, cependant, vous devez avoir des listes séparées pour chaque dimension des indices. Ce qui signifie que vous ne pouvez pas faire:

a = np.random.randn(7, 8, 9)  # 3D array
b = [(2, 3, 0), (5, 4, 1), (1, 2, 2), (1, 0, 3)]
print(a[b])  # this is incorrect

mais vous pouvez faire:

[a[b[x]] for x in range(b.shape[0])]

vous pouvez également utiliser np.take :

a[b]


0 commentaires

-1
votes

J'ai résolu ce problème en écrivant une extension C à numpy appelée Tensor Weighted Interpolative Transfer, afin d'obtenir de la vitesse et du multi-threading. En python pur, c'est 3 secondes pour une échelle d'image de 200x100x3 et un fondu à travers, et en C multi-thread avec 8 cœurs, c'est 0,5 millisecondes pour la même opération.

Le code C de base a fini par ressembler à

t2[dstidxs2[i2] + doff1] += t1[srcidxs2[i2] + soff1] * w1 * ws2[i2];

Où doff1 est le décalage dans le tableau de destination etc. Les w1 et ws2 sont les poids interpolés. Tout le code est ultra optimisé en C pour la vitesse. (pas la taille du code ni la maintenabilité)

Tout le code est disponible sur https://github.com / RMKeene / twit et sur PyPI.

Je m'attends à une optimisation de furthur dans le futur, comme des cas spéciaux si tous les poids sont de 1,0.


0 commentaires