J'ai une tâche très simple et numpy fait quelque chose que je ne comprends pas. J'essaie de remplacer les éléments d'un tableau qui répondent à certains critères par un nombre compris entre 0 et 1, et numpy les convertit tous en zéros. Par exemple:
In [1]: some_array = np.array([0,0,0,1,0,1,1,1,0]) In [2]: nonzero_idxs = np.where(some_array != 0)[0] In [3]: nonzero_idxs Out[3]: array([3, 5, 6, 7]) In [4]: some_array[nonzero_idxs] = 99 In [5]: some_array Out[5]: array([ 0, 0, 0, 99, 0, 99, 99, 99, 0]) In [6]: some_array[nonzero_idxs] = 0.2 In [7]: some_array[nonzero_idxs] Out[7]: array([0, 0, 0, 0]) In [8]: some_array[nonzero_idxs] == 0 Out[8]: array([ True, True, True, True], dtype=bool)
Comme le montre l'exemple ci-dessus, le remplacement des valeurs par une valeur arbitraire fonctionne comme prévu, mais si vous essayez de le remplacer par un décimal, il le transforme en zéro (et ils ne vous contentez pas de ressembler à des zéros lorsque vous imprimez le tableau, ils évaluent comme étant égaux à zéro). Le même comportement se produit lorsque j'essaye de procéder autrement, par exemple en utilisant np.place.
Je fais cela dans iPython sur le terminal, si cela fait une différence. Quelqu'un peut-il expliquer ce qui se passe ici et comment l'éviter? Toutes mes excuses s'il s'agit d'un doublon.
3 Réponses :
nonzero_idxs = np.where(some_array != 0)[0] some_array[nonzero_idxs] = 0.2 # output: array([0. , 0. , 0. , 0.2, 0. , 0.2, 0.2, 0.2, 0. ])
La raison est simple.
Contrairement aux listes Python, les tableaux numpy ne peuvent contenir que des éléments d'un certain type et de ses sous-types.
Lorsque vous avez défini some_array , il a été créé en tant que tableau int32 . Par conséquent, lorsque vous avez essayé de lui attribuer une valeur de type float , elle a été forcée à un int et int (0.2) == 0 code >.
Comparez avec le cas où vous spécifiez que le tableau doit contenir float32:
array([0. , 0. , 0. , 0.2, 0. , 0.2, 0.2, 0.2, 0. ])
Sortie: p >
some_array = np.array([0, 0, 0, 1, 0, 1, 1, 1, 0], dtype=np.float) nonzero_idxs = np.where(some_array != 0)[0] some_array[nonzero_idxs] = 0.2 some_array
Le problème est dtype . C'est int64 , et vous devez le changer en float64 (ou simplement float ):
some_array = some_array.astype ('float')
Remarque: ce ne sera pas int64 sous Windows - ce sera int32 . Cela peut conduire à des débordements inattendus et silencieux dans des éléments tels que sum () , il convient donc de garder à l'esprit.
Je viens de l'essayer sur Windows avec Jupyter, et c'est int64 par défaut. Cela dépend peut-être de l'architecture.
Jupyter intervient alors. Il ne doit pas être int64 en Python. Quelle version de Windows? Peut-être ont-ils changé le type int par défaut dans Windows 10
OK oui, j'ai juste essayé le même test il y a une seconde ... il sort comme 5. Alors ... pourquoi est-ce que ça les force à être des entiers? Cela me semble un comportement étrange.
Merci @pault. La réponse est enfouie dans les réponses à cette question. Si le tableau ne contient que des entiers, il refuse de vous permettre de remplacer un élément par un flottant. Vous devez faire quelque chose comme some_array = some_array.astype (float). Je n'aurais jamais pensé cela tout seul.
Peut-être que cette question devrait être close en double de celle-ci.