2014-01-31 83 views
2

我想與numba使用numpy,但我得到奇怪的結果,同時嘗試訪問或設置一些值爲浮點型數組使用浮點型索引轉換爲int 。 檢查這個基本功能。在Python/Numba中訪問數組給出奇怪的結果

@numba.jit("void(f8[:,::1],f8[:,::1])") 
def test(table, index): 
x,y = int(index[0,0]), int(index[1,0) 
table[y,x] = 1.0 
print index[0,0], index[1,0], x,y 
print table 
print table[y,x] 

table = np.zeros((5,5), dtype = np.float32) 
index = np.random.ranf(((2,2)))*5 
test(table, index) 

結果:

index[0,0] = 1.34129550525 index[1,0] = 0.0656177324359 x = 1 y = 0  
table[0,1] = 1.0 
table [[ 0.  0.  1.875 0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ] 
     [ 0.  0.  0.  0.  0. ]] 

爲什麼我能在這個表中的1.875,而不是1.0?這是一個基本的例子,但我正在與大數組一起工作,它給了我很多錯誤。我知道我可以將索引轉換爲np.int32並更改@ numba.jit(「void(f8 [:,:: 1],f8 [:,1])」)@ numba.jit (「void(f8 [:,:: 1],i4 [:,:: 1])」),這是工作正常,但我想你想明白爲什麼這是行不通的。 從python解析類型到C++時它是一個問題?

感謝您幫助

+0

沒有在JIT的F8聲明和初始化np.float32之間的差異? 1.875不在x = 1處。 順便說一句,爲什麼它被標記爲C++? – Joky

+0

@Joky C++標籤是一個錯誤的抱歉。是的,它與np.float64一起工作。 但對於像1.0這樣的數字應該浮動32或浮動64有所作爲? –

+0

既然您標記了C++;):問題是該表是一個指向double的指針,指向一個float數組。在位置1重疊位置3/4的浮點數(2倍大)和在兩個浮點數上的雙精度編碼沒有任何意義。順便說一句,這是一個猜測,因爲我不知道什麼是numba生成的代碼。編輯:unutbu下面解釋清楚。 – Joky

回答

4
In [198]: np.float64(1.0).view((np.float32,2)) 
Out[198]: array([ 0. , 1.875], dtype=float32) 

所以當

table[y,x] = 1.0 

寫入np.float64(1.0)tabletable視圖中的數據爲np.float32和其解釋爲0和1.875。

注意,在0索引位置[0,1]顯示出來,並1.875顯示出來在索引位置[0,2],而分配發生在[y,x] = [0,1]

您可以通過改變

@numba.jit("void(f8[:,::1],f8[:,::1])") 

修復D型不匹配

@numba.jit("void(f4[:,::1],f8[:,::1])") 

這些是8個字節np.float64(1.0)

In [201]: np.float64(1.0).tostring() 
Out[201]: '\x00\x00\x00\x00\x00\x00\xf0?' 

而且4個字節時'\x00\x00\xf0?'被解釋爲np.float32你得到1.875:

In [205]: np.fromstring('\x00\x00\xf0?', dtype='float32') 
Out[205]: array([ 1.875], dtype=float32) 
+0

非常感謝。也許這是一個愚蠢的問題,但爲什麼np.float64和np.float32之間的區別? –

+0

'np.float64'表示一個64位(8字節)的浮點數。 'np.float32'代表一個32位(4字節)的浮點數。 'np.float(1。0)'佔用8個字節。如果將它寫入'table',則覆蓋8個字節。當「table」被打印時,它將其基礎數據解釋爲4字節的浮點數,所以你寫了'table'中的2個值(浮點數)。 – unutbu

+0

好吧,我知道float64是8字節和float32 4個字節。但我認爲字節數只是改變了你可以寫的最大數量。不是這個數字的寫法。例如np.int32(1).tostring()給出'\ x01 \ x00 \ x00 \ x00'和np.int64(1).tostring()給出'\ x01 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00',即使浮點數和整數不同,我認爲np.float64會給 '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x80?' –