1

ich eine Liste von Indizes gefällt:Füllen Sie bestimmte Indizes von einem 3d numpy Array

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

Und eine Liste von Werten wie folgt aus:

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

Beide haben 500 Einträge. Jetzt möchte ich ein 3d numpy Array mit diesen Werten auf dem rechten Index füllen. Was ich versuchte das zu tun folgenden:

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] 

Wenn ich drucke den Index und den Wert in dieser Schleife ich das richtige Format zu bekommen, aber wenn ich die Matrix nach der Schleife drucken scheint es, wie die Werte gesetzt worden dort mehrmals statt nur auf den angegebenen Indizes. Was mache ich falsch?

+0

Ich schrieb 30 im ersten Index als ein Beispiel, ich weiß, das ist außerhalb des Bereichs. Dies ist in den tatsächlichen Daten nicht der Fall. – maxmijn

Antwort

4

Sie sollten vermeiden, immer wenn es möglich ist, über numpy Arrays zu schleifen, sonst verlieren Sie die Leistung. Sie können advanced ("fancy") indexing verwenden, um eine Teilmenge von Elementen bei bestimmten Indizes zu indizieren. Dies wäre etwa so funktionieren:

brain_map[ind_x,ind_y,ind_z] = vals 

wo ind_x, ind_y, ind_z und vals sind alle 1D-Array-likes von gleicher Länge. Was Sie haben, ist im Wesentlichen die Transponierung des Indexfeldes:

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

Der zip(*) Trick transponiert im Wesentlichen Ihre Liste von Listen, die dann als ein Tupel für die Indizierung übergeben werden können. Zum Beispiel:

>>> 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

Vielen Dank! Abgesehen von der schlechten Vorgehensweise beim Schleifen von Arrays funktionierte der Code nicht, weil ich keine Tupel für die Indizierung verwendete. – maxmijn

+0

@maxmijn erweiterte Indexierung kann im allgemeinen Fall wirklich kompliziert sein. Die kurze Antwort auf Ihre Frage ist "Ja": das grundlegende (dh nicht-ausgefallene) Indexierungsschema 'M [i, j, k]' steht eigentlich für 'M [(i, j, k)]' aufgrund der impliziten Pythons Tupelsyntax. Wenn Sie etwas anderes als ein Tupel (normalerweise eine Liste oder ein Array) als Index verwenden, kann dies eine ausgefallene Indizierung auslösen. Also gibt 'M [[i, j, k]]' Ihnen ein Array, das 'M [i]', 'M [j]' und 'M [k]' enthält, die jeweils implizit "M [i" entsprechen: ,:] ',' M [j,:,:] ',' M [k,:,:] 'bzw.. Vergleichen Sie zum Beispiel 'M [0,1,0]' mit 'M [[0,1,0]]'. Letzteres ist ein 3D-Array. –

Verwandte Themen