2012-05-24 30 views
24

¿El siguiente comportamiento numpy es intencional o es un error?Por qué Numpy trata a + = b y a = a + b de manera diferente

from numpy import * 

a = arange(5) 
a = a+2.3 
print 'a = ', a 
# Output: a = 2.3, 3.3, 4.3, 5.3, 6.3 

a = arange(5) 
a += 2.3 
print 'a = ', a 
# Output: a = 2, 3, 4, 5, 6 

versión de Python: 2.7.2, versión Numpy: 1.6.1

Respuesta

41

Eso es intencional. El operador += conserva el tipo de matriz. En otras palabras, una matriz de enteros sigue siendo una matriz de enteros.

Esto permite a NumPy realizar la operación += utilizando el almacenamiento de matriz existente. Por otro lado, a=a+b crea una nueva matriz para la suma y vuelve a enlazar a para apuntar a esta nueva matriz; esto aumenta la cantidad de almacenamiento utilizado para la operación.

citar el documentation: Advertencia

: En las operaciones lugar llevará a cabo el cálculo utilizando la precisión decidido por el tipo de datos de los dos operandos, sino que en silencio abatido el resultado (si es necesario) por lo puede encajar de nuevo en la matriz. Por lo tanto, para cálculos de precisión mixta, A {op}= B puede ser diferente de A = A {op} B. Por ejemplo, suponga a = ones((3,3)). Entonces, a += 3j es diferente de a = a + 3j: mientras ambos realizan el mismo cálculo, a += 3 arroja el resultado para encajar en a, mientras que a = a + 3j vuelve a enlazar el nombre a al resultado.

Por último, si usted se pregunta por qué a era una matriz de enteros, en primer lugar, tenga en cuenta lo siguiente:

In [3]: np.arange(5).dtype 
Out[3]: dtype('int64') 

In [4]: np.arange(5.0).dtype 
Out[4]: dtype('float64') 
+0

Entiendo que a es un número entero, sin embargo, el resultado esperado en Python de agregar flotantes y números enteros es un flotante, por lo que esta es una "característica" inesperada – Dhara

+4

@Dhara: Estoy de acuerdo con que esto puede ser inesperado . También puede ser útil. En cualquier caso, he agregado una cita de la documentación que explica el comportamiento. – NPE

+0

Las operaciones in situ pueden ser mucho más rápidas (sin asignación, mejor utilización de la memoria caché), y si puede conservar todas las referencias existentes a esta matriz (si tiene estructuras de datos peludas). También estos son muy útiles para programadores de C/C++/Fortran fondos. –

8

@aix es completamente correcto. Solo quería señalar que esto no es exclusivo de numpy. Por ejemplo:

>>> a = [] 
>>> b = a 
>>> a += [1] 
>>> print a 
[1] 
>>> print b 
[1] 
>>> a = a + [2] 
>>> print a 
[1, 2] 
>>> print b 
[1] 

Como se puede ver += modifica la lista y + crea una nueva lista. Esta espera para numpy también. + crea una nueva matriz para que pueda ser cualquier tipo de datos. += modifica la matriz in situ y no es práctico, y tampoco es deseable, para que numpy cambie el tipo de datos de una matriz cuando se modifica el contenido de la matriz.

+0

Buen punto, gracias – Dhara

Cuestiones relacionadas