Détails
Remplacez tous les éléments d'un tableau Python NumPy qui sont supérieurs à une certaine valeur.
J'ai un tableau NumPy 2D et je voudrais remplacer toutes les valeurs supérieures ou égales à un seuil T par 255.0. À ma connaissance, la méthode la plus fondamentale serait la suivante :
shape = arr.shape
result = np.zeros(shape)
for x in range(0, shape[0]):
for y in range(0, shape[1]):
if arr[x, y] >= T:
result[x, y] = 255
-
Quelle est la manière la plus concise et la plus pythique de le faire ?
-
Existe-t-il un moyen plus rapide (peut-être moins concis et/ou moins pythonique) de faire cela ?
Ceci fera partie d'une sous-routine d'ajustement de fenêtre/niveau pour les scans IRM de la tête humaine. Le tableau numpy 2D est le pixel de l'image.
165
3
Je pense que le moyen le plus rapide et le plus concis de le faire est d'utiliser l'indexation fantaisiste intégrée de NumPy. Si vous avez un
ndarray
nomméarr
, vous pouvez remplacer tous les éléments>255
par une valeurx
comme suit :J'ai exécuté cette opération sur ma machine avec une matrice aléatoire de 500 x 500, en remplaçant toutes les valeurs >0.5 par 5, et cela a pris en moyenne 7.59ms.
Puisque vous voulez en fait un tableau différent qui est
arr
oùarr < 255
, et255
sinon, cela peut être fait simplement :Plus généralement, pour une borne inférieure et/ou supérieure :
Si vous voulez juste accéder aux valeurs supérieures à 255, ou quelque chose de plus compliqué, la réponse de @mtitan8'est plus générale, mais
np.clip
etnp.minimum
(ounp.maximum
) sont plus jolis et beaucoup plus rapides pour votre cas :Si vous voulez le faire in-place (c'est-à-dire modifier
arr
au lieu de créerresult
), vous pouvez utiliser le paramètreout
denp.minimum
:ou
(le nom
out=
est facultatif puisque les arguments sont dans le même ordre que la définition de la fonction).Pour la modification en place, l'indexation booléenne accélère beaucoup (sans avoir à faire et à modifier la copie séparément), mais n'est toujours pas aussi rapide que
minimum
:A titre de comparaison, si vous vouliez restreindre vos valeurs avec un minimum ainsi qu'un maximum, sans
clip
vous devriez le faire deux fois, avec quelque chose commeou,
Vous pouvez envisager d'utiliser [numpy.putmask][1] :
Voici une comparaison des performances avec l'indexation intégrée de Numpy :
[1] : http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.putmask.html