我正在寻找程序中的错误,我发现它是由 Numpy 的意外行为产生的......
例如,当使用 Python3k 和 Numpy 对不同整数类型进行简单的算术运算时,例如
(numpy.uint64) + (int)
结果是......一个 numpy.float64
这是一个例子:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(v[0])
v[0] += 1
print(v[0])
它产生以下结果:
10000000000000001
10000000000000000
当您处理整数以避免舍入错误时,这可能是非常出乎意料的......
通过将 1 替换为 numpy.uint64(1) 可以轻松解决上述“问题”,但我可以看到很多错误来自于此。这种情况背后的规则和逻辑是什么?在这种情况下,是否有任何关于强制执行方式的文档?我找不到它。
我之前以为你可以通过使用 .item() 对强制有一些了解,但它更具误导性:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(type(v[0].item()))
v[0] = v[0].item() + 1
print(v[0])
生产
<class 'int'>
10000000000000001
10000000000000002
所以 .item() 将 numpy.uint64 转换为 int,如果你在算术运算中明确使用它,它就可以工作。
我很惊讶(但我猜我缺乏 numpy 经验),当 'a' 对应于 numpy 特定的 dtype 时,
a.item() + 1
和
a + 1
不要产生相同的结果......因此在转换回 numpy dtype 时会给出不同的结果。
(使用的环境是最新的 Pyzo 发行版,通过 IEP,如果重要的话。我通常使用 Python 2,但我必须在 Py3k 中进行一些测试,这是一种方便的方法。)