意外的Numpy / Py3k强制规则

时间:2015-07-28 12:41:08

标签: python numpy typing coerce

我正在寻找程序中的错误,我发现它是由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

当你处理整数以避免舍入错误时,这可能是非常意外的......

通过用numpy.uint64(1)替换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,如果你明确地在算术运算中使用它,它就可以工作。

我很惊讶(但我没有经验,我猜),当'a'对应于numpy特定的dtype时,

a.item() + 1

a + 1

不会产生相同的结果......因此在转换回numpy dtype时会产生不同的结果。

(使用的环境是最新的Pyzo发行版,通过IEP,如果重要的话。我通常使用Python 2,但我必须在Py3k中进行一些测试,这是一种方便的方法。)

1 个答案:

答案 0 :(得分:0)

如上所述:

它适用于:

dtype=np.int64 

而不是:

dtype=np.uint64 

对于python 2和3,numpy 1.6和1.9。

只需使用:

np.int64

没有理由使用uint642⁶⁴ - 12⁶³ - 1的溢出对于所有实际目的来说都是完全相同的。

<强>参考