2017-09-04 5 views
1

forループからベクトル化numpy操作への非常に簡単な移行では、バグを把握することはできません。それは2D行列間の単純な加算であるので、コードは以下のpython forループと3次元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, :, :]) 

で、私は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 x M x C x(C + 1)の行列で、posteriorsはN x L x C x(C + 1)です。それは次元に依存しないので私の更新を見てください(私は1分で投稿します)、私は信じています – diningphil

答えて

1

問題はbasic indexingとは対照的に、あなたは(advanced indexingを使用しているので、渡すout=singletree[null_positions, parent.x, :, :]を返す、singletreeの一部のコピーを作成していることである(離れて新しい行列を割り当てるから、私は、意味的な側面に興味があります)ビュー)。したがって、結果はまったく異なる配列に書き込まれ、元の配列は変更されません。

ただし、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

関連する問題