Die Verwendung von mehreren Ebenen boolean index-Maske in NumPy
Ich habe den folgenden code die erste wählt Elemente ein NumPy-array mit einem logischen index-Maske:
import numpy as np
grid = np.random.rand(4,4)
mask = grid > 0.5
Ich möchte eine zweite boolean-Maske gegen diese eine herausgreifen Objekte mit :
masklength = len(grid[mask])
prob = 0.5
# generates an random array of bools
second_mask = np.random.rand(masklength) < prob
# this fails to act on original object
grid[mask][second_mask] = 100
Dies ist nicht ganz das gleiche problem wie in dieser Frage ALSO:
Numpy-array, wie wählen Indizes befriedigend mehreren Bedingungen? - so wie ich bin mit Zufallszahl-generation, ich will nicht zu haben, um zu generieren, eine vollständige Maske, die nur die Elemente ausgewählt, die durch die erste Maske.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Glaube ich, dass die folgenden tut, was Sie gefragt haben:
Funktioniert es wie folgt:
np.where(mask)
konvertiert den booleschen Maske in die Indizes, womask
ist Wahr;[a[second_mask] for a in ...]
Untergruppen der Indizes wählen Sie nur diejenigen, in denensecond_mask
Wahr ist.Den Grund Ihrer ursprünglichen version nicht funktioniert, ist, dass
grid[mask]
beinhaltet fancy indexing. Dies erstellt eine Kopie der Daten, die wiederum Ergebnisse in...[second_mask] = 100
ändern, dass die Kopie statt das original-array.np.where
unda[second_mask]
. Die Größe dieser arrays hängt von der Anzahl der True-Elemente inmask
undsecond_mask
und ist unabhängig von der Größe dergrid
.grid[mask & second_mask]
.Flat Indizierung vermeidet viel von den Kopfschmerzen:
ZERLEGUNG:
erzeugt ein flaches array von Indizes, wo
mask
true ist, dann wird weiter dezimiert durch die Anwendungsecond_mask
:Könnten wir weitermachen:
Schließlich
Indizes eine flache version von
grid
mitind
und weist100
.grid.ravel()[ind] = 100
auch funktionieren würde, daravel()
gibt eine flache Ansicht in das original-array.Andere Lösung die ich mir ausgedacht habe nach zu denken über diese ein wenig mehr zu haben, die zweite Karte zu behalten die Größe der ersten (die kann oder kann nicht lohnen, den Arbeitsspeicher Treffer) und fügen Sie selektiv in der neuen Elementen:
Obwohl dies ein wenig länger, es scheint besser lesbar (für meine Anfänger Augen), und bei speed-tests führt er in der gleichen Zeit.