プログラムのバグを探していたところ、Numpy の予期しない動作が原因であることがわかりました...
たとえば、Python3k と Numpy を使用してさまざまな整数型に対して単純な算術演算を行う場合、次のようになります。
(numpy.uint64) + (整数)
結果は... 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に変換すると異なる結果が得られます。
(使用された環境は、IEP 経由の最新の Pyzo ディストリビューションです。私は通常 Python 2 を使用しますが、Py3k でいくつかのテストを行う必要があり、それはそれを行う便利な方法でした。)