Remplacer les valeurs d'un tableau d'index numpy par les valeurs d'une liste
supposons que vous ayez un tableau nummpy et une liste:
>>> a = np.array([1,2,2,1]).reshape(2,2)
>>> a
array([[1, 2],
[2, 1]])
>>> b = [0, 10]
j'aimerais remplacer les valeurs dans un tableau, de sorte que 1 soit remplacé par 0, et 2 par 10.
j'ai trouvé un problème similaire ici - http://mail.python.org/pipermail//tutor/2011-September/085392.html
Mais en utilisant cette solution:
for x in np.nditer(a):
if x==1:
x[...]=x=0
elif x==2:
x[...]=x=10
me Lance une erreur:
ValueError: assignment destination is read-only
je suppose que c'est parce que je ne peux pas vraiment écrire dans un numpy array.
P. La taille réelle du tableau numpy est 514 par 504 et de la liste est de 8.
5 réponses
au lieu de remplacer les valeurs un par un, il est possible de refaire le tableau entier comme ceci:
import numpy as np
a = np.array([1,2,2,1]).reshape(2,2)
# palette must be given in sorted order
palette = [1, 2]
# key gives the new values you wish palette to be mapped to.
key = np.array([0, 10])
index = np.digitize(a.ravel(), palette, right=True)
print(key[index].reshape(a.shape))
les rendements
[[ 0 10]
[10 0]]
le mérite de l'idée ci-dessus revient à @ JoshAdel. Il est nettement plus rapide que ma réponse originale à cette question:
import numpy as np
import random
palette = np.arange(8)
key = palette**2
a = np.array([random.choice(palette) for i in range(514*504)]).reshape(514,504)
def using_unique():
palette, index = np.unique(a, return_inverse=True)
return key[index].reshape(a.shape)
def using_digitize():
index = np.digitize(a.ravel(), palette, right=True)
return key[index].reshape(a.shape)
if __name__ == '__main__':
assert np.allclose(using_unique(), using_digitize())
j'ai comparé les deux versions de cette façon:
In [107]: %timeit using_unique()
10 loops, best of 3: 35.6 ms per loop
In [112]: %timeit using_digitize()
100 loops, best of 3: 5.14 ms per loop
Eh bien, je suppose que ce dont vous avez besoin est
a[a==2] = 10 #replace all 2's with 10's
Lecture seule matrice dans numpy peut être rendue accessible en écriture:
nArray.flags.writeable = True
cela permettra alors des opérations d'assignation comme celle-ci:
nArray[nArray == 10] = 9999 # replace all 10's with 9999's
le vrai problème n'était pas l'assignation elle-même mais le drapeau inscriptible.
vous pouvez aussi utiliser np.choose(idx, vals)
, où idx
est un tableau d'indices qui indiquent la valeur de vals
devrait être mis à leur place. Les indices doivent être basés sur 0. Assurez-vous également que idx
a un type de données entier. Donc, vous n'aurez qu'à faire:
np.choose(a.astype(np.int32) - 1, b)