Подтвердить что ты не робот

Почему Numpy рассматривает a + = b и a = a + b по-разному

Является ли следующее поведение numpy преднамеренным или это ошибка?

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

Версия для Python: 2.7.2, версия для номенклатуры: 1.6.1

4b9b3361

Ответ 1

Это намеренное.

Оператор += сохраняет тип массива. Другими словами, массив целых чисел остается массивом целых чисел.

Это позволяет NumPy выполнять операцию += с использованием существующего хранилища массивов. С другой стороны, a=a+b создает совершенно новый массив для суммы и переупорядочивает a, чтобы указать на этот новый массив; это увеличивает объем памяти, используемой для операции.

Чтобы процитировать документацию:

Предупреждение: На месте операции будут выполняться вычисления с использованием точности, определяемой типом данных двух операндов, но будет тихо опускать результат (если необходимо), чтобы он мог поместиться обратно в массив, Поэтому для смешанных вычислений точности A {op}= B может отличаться от A = A {op} B. Например, предположим a = ones((3,3)). Тогда a += 3j отличается от a = a + 3j: в то время как оба они выполняют одно и то же вычисление, a += 3 возвращает результат, чтобы он возвращался в a, тогда как a = a + 3j повторно связывает имя a с результатом.

Наконец, если вам интересно, почему a был целым массивом в первую очередь, рассмотрите следующее:

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

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

Ответ 2

@aix совершенно прав. Я просто хотел указать, что это не уникально для numpy. Например:

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

Как вы видите, += изменяет список, а + создает новый список. Это значение также имеет значение numpy. + создает новый массив, поэтому он может быть любым типом данных. += изменяет массив inplace, и это непрактично, и желательно, чтобы numpy изменял тип данных массива при изменении содержимого массива.