1

J'ai une liste d'indices aime ça:Remplissez certains indices d'un tableau 3d numpy

selected_coords = [[1, 8, 30], [15, 4, 6] ,...] 

Et une liste de valeurs comme ceci:

differences = [1, 5, 8, 2, ...] 

deux ont 500 entrées. Maintenant, je veux remplir un tableau numpy 3d avec ces valeurs sur l'index de droite. Ce que j'ai essayé de faire est la suivante:

brain_map = np.zeros(shape=(48,60,22)) 

for i, index in enumerate(selected_coords): 
    ind = list(map(int, index)) 
    brain_map[ind] = differences[i] 

Si j'imprimer l'index et la valeur dans cette boucle, je reçois le format, mais si j'imprime la matrice après la boucle, il semble que les valeurs ont été mises là-bas plusieurs fois au lieu de seulement sur les indices spécifiés. Qu'est-ce que je fais mal?

+0

J'ai écrit 30 dans le premier index à titre d'exemple, je sais que c'est hors de portée. Ce n'est pas le cas dans les données réelles. – maxmijn

Répondre

4

Vous devriez éviter de faire une boucle sur des tableaux chiffrés autant que possible, sinon vous perdez des performances. Vous pouvez utiliser advanced ("fancy") indexing pour indexer un sous-ensemble d'éléments à des index spécifiques. Cela fonctionne comme ceci:

brain_map[ind_x,ind_y,ind_z] = vals 

ind_x, ind_y, ind_z et vals sont tous 1d tableau-goûts de la même longueur. Ce que vous avez est essentiellement la transposition de vos tableaux d'index:

brain_map[tuple(zip(*selected_coords))] = differences 

L'astuce zip(*) essentiellement votre liste transpose des listes, qui peuvent ensuite être transmis comme tuple pour l'indexation. Par exemple:

>>> import numpy as np 
>>> M = np.random.rand(2,3,4) 
>>> coords = [[0,1,2],[1,2,3]] 
>>> tuple(zip(*coords)) 
((0, 1), (1, 2), (2, 3)) 
>>> M[tuple(zip(*coords))] 
array([ 0.12299864, 0.76461622]) 
>>> M[0,1,2],M[1,2,3] 
(0.12299863762892316, 0.76461622348724623) 
+0

Merci beaucoup! Donc essentiellement, en dehors de la mauvaise pratique de la mise en boucle des tableaux, le code ne fonctionnait pas parce que je n'utilisais pas les tuples pour l'indexation? – maxmijn

+0

@maxmijn l'indexation avancée peut être vraiment compliquée dans le cas général. La réponse courte à votre question est "oui": le schéma d'indexation de base (ie non-fantaisie) 'M [i, j, k]' représente en fait 'M [(i, j, k)]' en raison de l'implicite de python syntaxe de tuple. Si vous utilisez autre chose qu'un tuple (généralement une liste ou un tableau) en tant qu'index, cela peut déclencher une indexation de fantaisie. Donc 'M [[i, j, k]]' vous donne un tableau qui contient 'M [i]', 'M [j]' et 'M [k]', chacun correspondant implicitement 'M [i ,: ,:] ',' M [j,:,:] ',' M [k,:,:] ', respectivement. Comparez 'M [0,1,0]' avec 'M [[0,1,0]]', par exemple. Ce dernier est un tableau 3d. –