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, le moyen le plus fondamental serait:
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 pythonique de faire cela?
Existe-t-il un moyen plus rapide (peut-être moins concis et / ou moins pythonique) de le faire?
Cela fera partie d'un sous-programme d'ajustement de la fenêtre / du niveau pour les examens IRM de la tête humaine. Le tableau numpy 2D correspond aux données de pixels de l'image.
Réponses:
Je pense que le moyen le plus rapide et le plus concis de le faire est d'utiliser l'indexation Fancy 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é ceci 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,59 ms.
la source
arr
, au lieu de créer unresult
tableau comme dans l'OP.A
mais en créant un nouveau tableau?np.array([1,2,3]
)Puisque vous voulez en fait un tableau différent qui soit
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 souhaitez simplement 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 agréables et beaucoup plus rapides pour votre cas:Si vous voulez le faire sur place (c'est-à-dire modifier
arr
au lieu de créerresult
), vous pouvez utiliser leout
paramètre denp.minimum
:ou
(le
out=
nom est facultatif car les arguments sont dans le même ordre que la définition de la fonction.)Pour la modification sur place, l'indexation booléenne accélère beaucoup (sans avoir à faire puis modifier la copie séparément), mais n'est toujours pas aussi rapide que
minimum
:À titre de comparaison, si vous vouliez restreindre vos valeurs avec un minimum ainsi qu'un maximum, sans
clip
vous auriez à le faire deux fois, avec quelque chose commeou,
la source
a[start:stop:step]
vous donne les éléments du tableau destart
àstop
, mais au lieu de chaque élément, il ne prend que tousstep
(si négligé, c'est1
par défaut ). Donc, pour mettre tous les égales à zéro, vous pouvez le fairea[::2] = 0
Je pense que vous pouvez y parvenir le plus rapidement en utilisant la
where
fonction:Par exemple, rechercher des éléments supérieurs à 0,2 dans un tableau numpy et remplacer ceux par 0:
la source
Vous pouvez envisager d'utiliser numpy.putmask :
Voici une comparaison des performances avec l'indexation intégrée de Numpy:
la source
Une autre façon consiste à utiliser
np.place
qui effectue un remplacement sur place et fonctionne avec des tableaux multidimensionnels:la source
np.place
c'était également plus lent par rapport à la méthode intégrée, bien que le contraire soit affirmé dans ce commentaire.Vous pouvez également utiliser
&
,|
(et / ou) pour plus de flexibilité:valeurs entre 5 et 10:
A[(A>5)&(A<10)]
valeurs supérieures à 10 ou inférieures à 5:
A[(A<5)|(A>10)]
la source