3

(32, 1024) の形をした NumPyndarrayがあり、32 個の信号測定値を保持します。これを 1024 要素の長い配列に結合し、32 個ごとに異なる重みを付けます。使用してnumpy.averageいましたが、重みは複雑で、average私の結果を捨てる合計に基づいて重みの正規化を実行します。

平均のコードを見ると、重みに信号配列を掛けてから、最初の軸を合計することで同じことを達成できることがわかりました。ただし、(32,) 重み配列を (32, 1024) 信号配列で乗算しようとすると、(32,) を (32, 1024) にブロードキャストできないため、次元の不一致が発生します。weights 配列を (32, 1) に再形成すると、すべてが期待どおりに機能しますが、かなり醜いコードになります。

avg = (weights.reshape((32, 1)) * data).sum(axis=0)

NumPy が (32,) 配列を (32, 1024) にブロードキャストできない理由を説明したり、加重平均を実行する別のより適切な方法を提案したりできますか?

4

1 に答える 1

7

(X,)および(X,Y)整形アレイ間の位置合わせのための一般的なセットアップ

なぜ に(32,)ブロードキャストできないのかという(32, 1024)と、形状が正しく揃っていないためです。回路図に入れると、次のようになります。

weights :         32
data    :  32 x 1024 

weightsの最初の軸に揃えられた の最初の軸である唯一の軸を揃える必要がありdataます。したがって、1 つの方法が toreshape2Dあることに気付いたように、2 番目の軸としてシングルトン ディメンションになるようにします。None/np.newaxisこれは、 :weights[:,np.newaxis]またはweights[:,None]単純な reshape :を使用して新しい軸を導入することで実現できますweights.reshape(-1,1)。したがって、回路図に戻ると、変更されたバージョンでは次のようになります。

weights[:,None] :  32 x    1
data            :  32 x 1024

形状が整列されたので、これら 2 つの間で一般的な要素単位の操作を実行して、結果の回路図を次のように表示できます -

weights[:,None] :  32 x    1
data            :  32 x 1024
result          :  32 x 1024

これはブロードキャストされweights、関連する要素単位の操作が実行され、data結果は になりresultます。

特定のケースと代替案の解決

前のセクションでの議論に続いて、要素ごとの乗算のケースを解決するために、それは次のようにweights[:,None]*dataなります。axis=0

(weights[:,None]*data).sum(axis=0)

きちんとした代替品を探しましょう!

きちんとした、おそらく直感的な方法の1つは、np.einsum-

np.einsum('i,ij->j',weights,data)

別の方法は、 の最初の軸に対して の最初のnp.dot軸を失うため、 を使用した行列乗算を使用することです。weightsdata

weights.dot(data)
于 2016-08-31T16:36:55.563 に答える