2017-03-07 38 views
0

我想知道是否會導致問題,因爲我正在Python2.7中錯誤地分配數據類型並將其轉換爲numpy數組。NumPy:將int64值存儲在np.array中並使用dtype float64並將其轉換回整數是否安全?

我在做的是從numpy.float64類型的numpy.zeros()數組中讀取hdf5 64位整數值!然後將這些值寫入另一個分配64位無符號整數的hdf5!

12028545243 
12004994169 

問題1:這實際上是ID號(所以至關重要的是,它們不改變由於數據類型轉換)某些原始值的

兩個示例將在該無符號整數第二個hdf5文件是否與原來的相同?

我用一個小子樣本檢查了這個,但我無法控制它們是否都是真的(有數百萬)!

問題2:如果我讀從原始文件到numpy的陣列數據類型= float64 64位的值,然後做這樣的事情:

value=int(value) 
value.astype(int64) 

那將是完全原始價值還是由於轉型而改變?

問題3: Python會解釋我假設的(a),(b),(c)和(d)的值嗎?如何使用科學記號'e + 10'也會對格式化數值產生影響?或者,Python是否將它們識別爲相同的值(因爲它只是一種顯示它們的不同方式......)?

1.20285452e+10 == 12028545243.0 == 12028545243 == 12028545243 
1.20049942e+10 == 12004994169.0 == 12004994169 == 12004994169 
(a)    (b)    (c)   (d) 

(a)中列出的值打印陣列命名的數據的一列:執行轉換後

print data[:,0] <type 'numpy.ndarray'> 

(b)中的打印數據

print data[0,0] <type 'numpy.float64'> 

(c)中的單個元素

print int(data[0,0]) <type int> 

(d)與(a)但使用astype()進行轉換!

print data[:,0].astype(numpy.int64) <type 'numpy.ndarray'> 

你可能會問,爲什麼我沒有分配一個int64類型到numpy數組是安全的?是的,我會這樣做,但有數據已經​​存儲錯誤,我需要知道,如果我仍然可以相信這些數據...

我正在使用:Python2.7,Pythonbrew,Ubuntu 14.04 LTS 64位在聯想T410

回答

0

通常,它不是保存在一個64位浮點64位整數。你可以很容易地看到,例如通過觀察:

import numpy as np 
print(np.int64(2**63-1)) 
print(np.int64(np.float64(2**63-1)) 

雖然第一會給你正確的結果(9223372036854775807),第二個有一個舍入誤差導致整數溢出(-9223372036854775808)。

要理解這一點,你必須看看這些數字是如何存儲的。雖然整數基本上只是將其絕對值存儲爲二進制數(加上一位用於數字的符號),但這不適用於浮點數。

浮點以三部分形式存儲一個數字。一個是符號位,下一個是重要/尾數,最後是指數。然後將該數字作爲符號時間的尾數時間2 ^指數給出。這三個必須分享可用的位(在你的情況64)。如numpy's documentation中所指定的那樣,52位用於有效位,11位用於指數。因此,只有對於高達52位的整數,如果將它們轉換爲np.float64並返回,您將確切地得到正確的結果。

所以回答你第一和第二個問題:沒有,如果有任何數字大於2**52-1在你的數據集,你不能確定這些數字都是相同的。

關於您的第三個問題:格式化僅在打印值時完成。在內部比較數字時,數字沒有任何格式,只要它們具有完全相同的值,所有這些值都將被視爲相等。

順便說一句,如果你想了解更多關於浮點運算的知識,一篇很好的文章是David Goldberg的文章"What every computer scientist should know about floating-point arithmetic"

+0

感謝您的幫助和解釋! – firefly2517

0

這取決於Numpy是否將您的int64值轉換爲float64,然後返回爲整數,或者只是將int數據存儲在爲float64保留的內存中。我假設第一種選擇是正確的。 即使沒有檢查float64內部(巫婆是一個人應該做的任何事情)。很明顯,如果浮點64只有2**64不同的代碼,並且還需要一些用於0.1等等,那麼float64不能具有對所有2**64不同整數的唯一表示。 Float64使用52位來存儲一個53位長的尾數(最顯著位是隱含1),所以如果你的INT有非零位的更多他們的第一個喜歡與後52位:

 5764607523034234887 
    = 0x5000000000000007 
    = 0b0101000000000000000000000000000000000000000000000000000000000111 

(女巫是一個完美的罰款64位整數)

0b111部分在最後將只是得到圓整和丟失後,將其轉換爲雙重,以適應數字到尾數。這些信息將永遠丟失。這可能會發生在你的一些ID,因爲他們通常是相當大的數字。 因此,請嘗試將您的數組調整爲int64。

+0

謝謝,幫忙!我以爲是這樣,希望我可以找到一個快速的解決方案,因爲我的身份證號碼不是那麼大,我只使用無符號。但似乎我必須從一開始就開始...... – firefly2517

相關問題