Pergunta sobre python, numpy – Por que Numpy trata a + = b e a = a + b de forma diferente

24

O seguinte comportamento numpy é intencional ou é um bug?

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

Versão Python: 2.7.2, versão Numpy: 1.6.1

Sua resposta

2   a resposta
41

Isso é intencional.

o+= operador preserva o tipo da matriz. Em outras palavras, uma matriz de inteiros permanece uma matriz de inteiros.

Isso permite que o NumPy execute o+= operação usando o armazenamento de matriz existente. Por outro lado,a=a+b cria uma nova matriz para a soma e reativaa para apontar para essa nova matriz; isso aumenta a quantidade de armazenamento usada para a operação.

Para citar odocumentação:

Aviso: As operações locais executarão o cálculo usando a precisão decidida pelo tipo de dados dos dois operandos, mas diminuirão silenciosamente o resultado (se necessário) para que ele possa voltar ao array. Portanto, para cálculos de precisão mista,A {op}= B pode ser diferente do queA = A {op} B. Por exemplo, suponhaa = ones((3,3)). Então,a += 3j é diferente do quea = a + 3j: enquanto ambos executam o mesmo cálculo,a += 3 lança o resultado para caber de voltaa, enquanto quea = a + 3j re-liga o nomea para o resultado.

Finalmente, se você está se perguntando por quea foi um array inteiro em primeiro lugar, considere o seguinte:

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

In [4]: np.arange(5.0).dtype
Out[4]: dtype('float64')
@Dhara: Eu concordo que isso pode ser inesperado quando for encontrado pela primeira vez. Também pode ser útil. De qualquer forma, eu adicionei uma citação da documentação que explica o comportamento. NPE
Eu entendo que a é um inteiro, no entanto, o resultado esperado em Python de adicionar um floats e inteiros é um float, então isso é um "recurso" inesperado Dhara
As operações no local podem ser muito mais rápidas (sem alocação, melhor utilização do cache) e se você puder manter todas as referências existentes a essa matriz (se tiver estruturas de dados cabeludas). Também são muito úteis para programadores de fundos C / C ++ / Fortran. Dima Tisnek
8

@aix está completamente certo. Eu só queria salientar que isso não é exclusivo para numpy. Por exemplo:

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

Como você pode ver+= modifica a lista e+ cria uma nova lista. Isso também serve para numpy.+ cria uma nova matriz para que possa ser qualquer tipo de dados.+= modifica o array no local e não é prático, e é desejável que o numpy altere o tipo de dados de um array quando o conteúdo do array é modificado.

Bom ponto, obrigado Dhara

Perguntas relacionadas