Sorry if this is a known issue, I searched for it but there are so many results...
This works:
import numpy as np
a = np.array([1, 2, 3])
a = a / 4
But this raises an error:
import numpy as np
a = np.array([1, 2, 3])
a /= 4
Namely:
TypeError: No loop matching the specified signature and casting
was found for ufunc true_divide
This is surprising since I would expect them to do the same.
Using numpy version 1.14.0.
I assume that you are on Python 3. This is expected behavior on Python 3. The result of a / 4
will not be an integer array but a floating point array. When you simply reassign that result with the line a = a / 4
, that's fine. It essentially converts the code to a = np.true_divide(a, 4)
which creates a new floating point array and reassigns the name a
to it.
When you try to do in-place assignment, the true_divide
ufunc is being asked to output back into the existing a
integer array: np.true_divide(a, 4, out=a)
. There is no implementation of true_divide
that takes two integer arguments and outputs another integer, so you get the exception.
Thanks for the clear explanation, that makes sense. The below helped me to understand the difference:
>>> 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
If I understand correctly, the fact that no new object is created with +=
, is the analogy to out=a
.
One way around the issue is to use dtype=float
upon array creation.
That's right.
Most helpful comment
I assume that you are on Python 3. This is expected behavior on Python 3. The result of
a / 4
will not be an integer array but a floating point array. When you simply reassign that result with the linea = a / 4
, that's fine. It essentially converts the code toa = np.true_divide(a, 4)
which creates a new floating point array and reassigns the namea
to it.When you try to do in-place assignment, the
true_divide
ufunc is being asked to output back into the existinga
integer array:np.true_divide(a, 4, out=a)
. There is no implementation oftrue_divide
that takes two integer arguments and outputs another integer, so you get the exception.