2017-09-04 69 views
1

我找不到一個從for循環到矢量化numpy操作的非常簡單的轉換中的錯誤。代碼如下蟒蛇for循環和3D numpy矩陣添加之間的等效

for null_pos in null_positions: 
     np.add(singletree[null_pos, parent.x, :, :], 
      posteriors[parent.u, null_pos, :, :], 
      out=singletree[null_pos, parent.x, :, :]) 

既然是2D矩陣之間的簡單相加,我概括成3D除了

np.add(singletree[null_positions, parent.x, :, :], 
      posteriors[parent.u, null_positions, :, :], 
      out=singletree[null_positions, parent.x, :, :]) 

的事情是,它出現的結果是不同的!你能明白爲什麼嗎?

謝謝!

更新: 看來

singletree[null_positions, parent.x, :, :] = \ 
      posteriors[parent.u, null_positions, :, :] + 
      singletree[null_positions, parent.x, :, :] 

解決了這個問題。這與添加操作有何不同? (除了分配一個新的矩陣,我感興趣的語義方面)

+0

輸入數組的形狀是什麼? –

+0

你可以假設:singletree是一個L×M×C×(C + 1)矩陣,後驗是N×L×C×(C + 1)。看看我的更新(我會在一分鐘後發佈),因爲它不依賴於尺寸,我相信 – diningphil

回答

1

的問題是,經過out=singletree[null_positions, parent.x, :, :]正在的singletree的部分的副本,因爲你正在使用advanced indexing(相對於basic indexing,它返回視圖)。因此,結果將被寫入完全不同的數組,並且原始數組將保持不變。

但是,you can use advanced indexing to assign values。在你的情況下,最值得推薦的語法是:

singletree[null_positions, parent.x, :, :] += \ 
    posteriors[parent.u, null_positions, :, :] 

這將盡量減少中間數組的使用。

+0

謝謝!這真是一個愚蠢的錯誤:) – diningphil

+0

@diningphil對我來說,看起來並不傻,你的代碼是完全合理的,但它只是「正常工作」或不依賴於你用什麼來索引數組......我的意思是這是有原因的,但這種陷阱比NumPy更常見。 – jdehesa

+0

我同意你的看法,這些都是棘手的情況。 – diningphil