Numpy: Division-assignment operator raises error, separate division and assignment work

Created on 9 Feb 2018  ·  3Comments  ·  Source: numpy/numpy

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.

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 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.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jakirkham picture jakirkham  ·  55Comments

rkern picture rkern  ·  166Comments

ricardoV94 picture ricardoV94  ·  53Comments

sturlamolden picture sturlamolden  ·  68Comments

mrava87 picture mrava87  ·  53Comments