2017-09-04 68 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