Lo siento si se trata de un problema conocido, lo busqué pero hay tantos resultados ...
Esto funciona:
import numpy as np
a = np.array([1, 2, 3])
a = a / 4
Pero esto genera un error:
import numpy as np
a = np.array([1, 2, 3])
a /= 4
A saber:
TypeError: No loop matching the specified signature and casting
was found for ufunc true_divide
Esto es sorprendente ya que esperaría que ellos hicieran lo mismo.
Usando numpy versión 1.14.0.
Supongo que está en Python 3. Este es el comportamiento esperado en Python 3. El resultado de a / 4
no será una matriz de enteros sino una matriz de punto flotante. Cuando simplemente reasigna ese resultado con la línea a = a / 4
, está bien. Básicamente, convierte el código en a = np.true_divide(a, 4)
que crea una nueva matriz de punto flotante y le reasigna el nombre a
.
Cuando intenta realizar una asignación en el lugar, se le pide a true_divide
ufunc que vuelva a generar la salida en la matriz de enteros a
: np.true_divide(a, 4, out=a)
. No hay una implementación de true_divide
que tome dos argumentos enteros y genere otro entero, por lo que obtiene la excepción.
Gracias por la explicación clara, eso tiene sentido. Lo siguiente me ayudó a comprender la diferencia:
>>> 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 lo entiendo correctamente, el hecho de que no se cree ningún objeto nuevo con +=
, es la analogía con out=a
.
Una forma de solucionar el problema es usar dtype=float
al crear la matriz.
Eso es correcto.
Comentario más útil
Supongo que está en Python 3. Este es el comportamiento esperado en Python 3. El resultado de
a / 4
no será una matriz de enteros sino una matriz de punto flotante. Cuando simplemente reasigna ese resultado con la líneaa = a / 4
, está bien. Básicamente, convierte el código ena = np.true_divide(a, 4)
que crea una nueva matriz de punto flotante y le reasigna el nombrea
.Cuando intenta realizar una asignación en el lugar, se le pide a
true_divide
ufunc que vuelva a generar la salida en la matriz de enterosa
:np.true_divide(a, 4, out=a)
. No hay una implementación detrue_divide
que tome dos argumentos enteros y genere otro entero, por lo que obtiene la excepción.