Désolé si c'est un problème connu, je l'ai recherché mais il y a tellement de résultats...
Cela marche:
import numpy as np
a = np.array([1, 2, 3])
a = a / 4
Mais cela génère une erreur :
import numpy as np
a = np.array([1, 2, 3])
a /= 4
À savoir:
TypeError: No loop matching the specified signature and casting
was found for ufunc true_divide
C'est surprenant car je m'attendrais à ce qu'ils fassent de même.
En utilisant numpy version 1.14.0.
Je suppose que vous êtes sur Python 3. C'est le comportement attendu sur Python 3. Le résultat de a / 4
ne sera pas un tableau d'entiers mais un tableau à virgule flottante. Lorsque vous réaffectez simplement ce résultat avec la ligne a = a / 4
, c'est bien. Il convertit essentiellement le code en a = np.true_divide(a, 4)
ce qui crée un nouveau tableau à virgule flottante et lui réaffecte le nom a
.
Lorsque vous essayez d'effectuer une affectation sur place, le true_divide
ufunc est invité à retourner dans le tableau d'entiers a
existant : np.true_divide(a, 4, out=a)
. Il n'y a pas d'implémentation de true_divide
qui prend deux arguments entiers et génère un autre entier, donc vous obtenez l'exception.
Merci pour l'explication claire, c'est logique. Ce qui suit m'a aidé à comprendre la différence :
>>> a = [1 ,2, 3]
>>> b = a
>>> id(a) == id(b)
True
>>> a += [4, 5, 6] # list object is changed, no new object created
>>> id(a) == id(b)
True
>>> a = a + [4, 5, 6] # new object created, and assigned to `a`
>>> id(a) == id(b)
False
Si je comprends bien, le fait qu'aucun nouvel objet ne soit créé avec +=
, est l'analogie avec out=a
.
Une façon de contourner le problème consiste à utiliser dtype=float
lors de la création du tableau.
C'est exact.
Commentaire le plus utile
Je suppose que vous êtes sur Python 3. C'est le comportement attendu sur Python 3. Le résultat de
a / 4
ne sera pas un tableau d'entiers mais un tableau à virgule flottante. Lorsque vous réaffectez simplement ce résultat avec la lignea = a / 4
, c'est bien. Il convertit essentiellement le code ena = np.true_divide(a, 4)
ce qui crée un nouveau tableau à virgule flottante et lui réaffecte le noma
.Lorsque vous essayez d'effectuer une affectation sur place, le
true_divide
ufunc est invité à retourner dans le tableau d'entiersa
existant :np.true_divide(a, 4, out=a)
. Il n'y a pas d'implémentation detrue_divide
qui prend deux arguments entiers et génère un autre entier, donc vous obtenez l'exception.