Le problème consiste à modéliser la propagation d'un signal (par exemple lumière ou son, etc.) à travers une série d'obstacles, comme sur la figure ci-dessous. Le signal ne peut pas traverser la surface inférieure (terrain), mais il peut traverser des obstacles. Je veux compter le nombre d'obstacles traversés.
Le terrain et les obstacles sont dans des tableaux numpy 2D (x, y, z). C'est ce que je fais:
output = numpy.zeros(terrain.shape)
obstacles = terrain + obstacle_heights
for i in xrange (obstacles.shape[0]):
for j in xrange (obstacles.shape[1]):
mask = obstacles[i,j] > terrain[i,j:]
output[i,j:][mask] +=1
Le résultat serait quelque chose comme [0, 0, 0, 1, 1, 1, 2, 3, 4, 4, 4 ...]
par ligne.
Cette méthode fonctionne bien (à condition que les vallées sur le terrain soient remplies en utilisant numpy.maximum.accumulate
). Maintenant, serait-il possible d'accélérer la chose en utilisant une solution vectorisée?
Réponses:
Comme le disent les commentaires ci-dessus, vous pouvez probablement vectoriser l'opération pour supprimer les boucles for et la rendre plus efficace.
Cependant, si vous envisagez le problème d'une manière légèrement différente - celle du seuillage - vous pouvez profiter des outils de scipy ndimage pour compter les obstacles:
Tout d'abord, limitez vos données de terrain en fonction de la hauteur de votre signal pour obtenir un tableau booléen de l'endroit où le signal pourrait être, quelle que soit l'origine.
Ensuite, vous pouvez utiliser la
ndimage.label
méthode pour regrouper des régions discrètes:Une fois cela fait, obtenez les identifiants de région qui correspondent aux cellules d'origine de votre signal. Dans votre cas, ce serait la première colonne.
Maintenant, le seuil est là où le signal intercepte le terrain + les obstacles, et cette fois, filtre les régions à l'extérieur ou la zone d'intérêt à l'aide
numpy.isin
.Et un dernier tour de
ndimage.label
vous donne un compte des obstacles interceptés, car nous avons déjà filtré les zones bloquées par le terrain:Il y a un peu plus de code ici, mais il y a deux gros avantages:
la source