J'ai le code suivant qui sélectionne d'abord des éléments d'une matrice numpue avec un masque d'index logique: Je souhaite utiliser un deuxième masque booléen contre celui-ci pour choisir des objets avec: P> 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
4 Réponses :
Je crois que ce qui suit fait ce que vous demandez: Cela fonctionne comme suit: p> La raison pour laquelle votre version d'origine ne fonctionne pas est que
np.where (masque) code> convertit le masque booléen dans les indices où masque code> est vrai; li>
[A [second_mask] pour un ...] code> sousfile les indices pour sélectionner uniquement ceux où second_mask code> est vrai. LI>
ul> grille [masque] code> implique une indexation fantaisie. Cela crée une copie des données, ce qui entraîne à son tour ... [second_mask] = 100 code> modifiant cette copie plutôt que le tableau d'origine. P> P>
Parfait, ce que je cherchais.
Vous y trouverez également une copie de tableaux impliqués dans l'extrait que vous avez posté?
@Hemmer: Il existe de nouveaux tableaux créés par np.where code> et A [second_mask] code>. La taille de ces tableaux dépend du nombre d'éléments vrais dans masque code> et second_mask code> et est indépendant de la taille de grille code>.
J'ai posté une solution alternative que j'ai trouvée au cas où vous seriez intéressé.
Il suffit de combiner des masques par grille [masque et second_mask] code>.
Une autre solution possible que j'ai proposée après avoir pensé à cela un peu plus est que la deuxième carte conserve la taille de la première (qui peut ou non la valeur de la mémoire) et d'ajouter de manière sélective dans les nouveaux éléments:
#!/usr/bin/env python import numpy as np prob = 0.5 grid = np.random.rand(4,4) mask = grid > 0.5 masklength = np.sum(mask) # initialise with false map second_mask = np.zeros((4,4), dtype=np.bool) # then selectively add to this map using the second criteria second_mask[mask] = np.random.rand(masklength) < prob # this now acts on the original object grid[second_mask] = 100
Utiliser l'indexation à plat évite une grande partie de la maux de tête:
grid.flat[ind] = 100
In [29]: ar = linspace(1,10,10) In [30]: ar[(3<ar)*(ar<8)] Out[30]: array([ 4., 5., 6., 7.])