Unexpected Numpy / Py3k enforcement rules
I was looking for an error in the program and I found that it was caused by unexpected behavior from Numpy ...
When doing, for example, a simple arithmetic operation for different integer types using Python3k and Numpy, for example
(numpy.uint64) + (int)
result: ... numpy.float64
Here's an example:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(v[0])
v[0] += 1
print(v[0])
This leads to the following result:
10000000000000001 10000000000000000
Which can be completely unexpected when you are dealing with integers to avoid rounding errors ...
The above "problem" can be easily solved by replacing 1 with numpy.uint64 (1), but I see a lot of errors coming from this. What are the rules and logic of this situation? Is there any documentation on how coercion is done in this case? I couldn't find it.
I used to think that you could get an idea of ββthe coercions with .item (), but this is even more misleading:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(type(v[0].item()))
v[0] = v[0].item() + 1
print(v[0])
produces
<class 'int'>
10000000000000001
10000000000000002
So .item () converts numpy.uint64 to int and if you explicitly use it in arithmetic operation it works.
I'm surprised (but I guess I lack experience with numpy) that when "a" matches a specific dtype,
a.item() + 1
and
a + 1
don't give the same results ... and thus gives different results when converted back to numpy dtype.
(The environment used is an updated Pyzo distribution via IEP, if that matters. I usually use Python 2, but I had to do a couple of tests in Py3k and it was a convenient way to do it.)
source to share