Извините, если это известная проблема, я искал ее, но результатов так много ...
Это работает:
import numpy as np
a = np.array([1, 2, 3])
a = a / 4
Но это вызывает ошибку:
import numpy as np
a = np.array([1, 2, 3])
a /= 4
А именно:
TypeError: No loop matching the specified signature and casting
was found for ufunc true_divide
Это удивительно, поскольку я ожидал, что они поступят так же.
Использование numpy версии 1.14.0.
Я предполагаю, что вы используете Python 3. Это ожидаемое поведение на Python 3. Результатом a / 4
будет не целочисленный массив, а массив с плавающей запятой. Когда вы просто переназначаете этот результат строкой a = a / 4
, это нормально. По сути, он преобразует код в a = np.true_divide(a, 4)
который создает новый массив с плавающей запятой и переназначает ему имя a
.
Когда вы пытаетесь выполнить назначение на месте, true_divide
ufunc запрашивается для вывода обратно в существующий массив a
integer: np.true_divide(a, 4, out=a)
. Не существует реализации true_divide
которая принимает два целочисленных аргумента и выводит другое целое число, поэтому вы получаете исключение.
Спасибо за ясное объяснение, которое имеет смысл. Приведенное ниже помогло мне понять разницу:
>>> 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
Если я правильно понимаю, тот факт, что новый объект не создается с помощью +=
, является аналогией с out=a
.
Один из способов решения проблемы - использовать dtype=float
при создании массива.
Верно.
Самый полезный комментарий
Я предполагаю, что вы используете Python 3. Это ожидаемое поведение на Python 3. Результатом
a / 4
будет не целочисленный массив, а массив с плавающей запятой. Когда вы просто переназначаете этот результат строкойa = a / 4
, это нормально. По сути, он преобразует код вa = np.true_divide(a, 4)
который создает новый массив с плавающей запятой и переназначает ему имяa
.Когда вы пытаетесь выполнить назначение на месте,
true_divide
ufunc запрашивается для вывода обратно в существующий массивa
integer:np.true_divide(a, 4, out=a)
. Не существует реализацииtrue_divide
которая принимает два целочисленных аргумента и выводит другое целое число, поэтому вы получаете исключение.