Вопрос по numpy, python – Почему Numpy по-разному относится к a + = b и a = a + b

24

Является ли следующее поведение 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, версия Numpy: 1.6.1

Ваш Ответ

2   ответа
41

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

Это позволяет 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')
Я понимаю, что a является целым числом, однако ожидаемый результат добавления Python и целых чисел в Python - это число с плавающей точкой, так что это неожиданная "особенность" Dhara
@ Дхара: Я согласен, что это может быть неожиданным при первом обнаружении. Это также может быть полезно. Во всяком случае, я добавил цитату из документации, которая объясняет поведение. NPE
Операции на месте могут быть намного быстрее (без выделения, лучшего использования кэша), и если вы можете сохранить все существующие ссылки на этот массив (если у вас есть волосатые структуры данных). Также они очень полезны для программистов из C / C ++ / Fortran. Dima Tisnek
8

@ Экс полностью прав.. Например

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

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

Хорошо, спасибо Dhara

Похожие вопросы