2015-07-28 93 views
3

我一直在尋找一個程序中的錯誤,我發現它是由來自numpy的一個意想不到的行爲產生...意外NumPy的/ Py3k強制規則

在做,例如,在不同的一個簡單的算術運算使用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,如果你明確地在算術運算中使用它,它就可以工作。

我很驚訝,(但我缺乏經驗numpy的,我猜),即,當 'A' 對應於一個特定的numpy的D類,

a.item() + 1 

a + 1 

不產生相同的結果......並因此在轉換回numpy dtype時給出不同的結果。我通常使用Python 2,但是我必須在Py3k中做一些測試,而且這是一個方便的方法來做到這一點。 。它)

+0

它正常工作與'D型= np.int64'代替'D型= np.uint64'(均爲蟒2和3,numpy的1.6和1.9)。我真的不明白爲什麼會這樣,聽起來像一個bug ...只要使用'np.int64',沒有理由使用'uint64',在'2⁶4 - 1'或'2⁶³ - 1'處溢出。對於所有的實際目的來說都是一樣的。 – rth

+1

這很有趣...確實,它適用於'dtype = np.int64' ...不知道它是否是一個錯誤(儘管它看起來像一個bug),因爲'np.int32 + int'和'np .uint32 + int'都轉換爲'np.int64',可能會避免溢出。爲什麼'np.int64 + int'變成'np.int64','np.uint64 + int'變成'np.float64'仍然沒有效果。我已經有很多解決方法,但我想知道是否有這個原因,以及我能在哪裏找到它。感謝您的評論... – Koren

+0

這裏是相應的[numpy問題](https://github.com/numpy/numpy/issues/5745),這使得在某些層次的敏感,但它仍然不是很直觀。 – rth

回答

0

正如上面指出:

它工作正常:

dtype=np.int64 

代替:

dtype=np.uint64 

python 2和3,numpy 1.6和1.9。

只需使用:

np.int64 

沒有理由使用uint64,在2⁶⁴ - 12⁶³ - 1四溢幾乎是所有的實際目的是一樣的。

參考

+0

我堅決不同意,它對於所有實際目的都是一樣的...... 在處理二進制數據時,我經常需要精確的整數類型。問題是舊的,但我認爲我當時需要它(我已經明確地使用它之前和之後)。用int64,你會有比較問題,並警告溢出。 這就是說,這只是一個意想不到的隱式轉換選擇,而且很容易規避,所以這不是一個真正的問題,但我認爲它應該在numpy文檔中更明顯。並不是說沒有充足的情況下,numpy文檔遠非完美:/ – Koren