2016-08-31 7 views
3

私はNumPy ndarrayの形状(32、1024)を持ち、32個の信号測定値を保持しています。私はnumpy.averageを使用していましたが、私の重みは複雑で、averageは私の結果を捨てる合計に基づいて重みの正規化を実行します。NumPy ndarrayブロードキャスト - シェイプ(X、)vs(X、1)

平均値のコードを見ると、信号配列で重みを掛けてから最初の軸を合計することで同じことを達成できることがわかりました。しかし、(32、1024)信号配列で私の(32、)ウェイト配列を乗算しようとすると、(32、)が(32、1024)にブロードキャストできないため、次元の不一致が生じます。私は重み配列の形状を変更した場合、予想通り(32、1)その後、すべての作品が、これはかなり醜いコードになります:numpyのはにブロードキャストするために私の(32)の配列を許可しない理由

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

誰も説明できます(32,1024)、あるいは加重平均を実行するための代替方法を提案するか?

+1

numpyは '(1,32)'から '(1024,32)'に展開できます。しかし、 '(32、)'を '(32,1)'に展開する許可を与えなければなりません。これにより、a(32、)にa(1024、)を掛けるなど、他の状況でのあいまいさを避けることができます。私の最近の答えでこれについて詳しくは、http://stackoverflow.com/a/39238203/901925 – hpaulj

答えて

4

(32,)(32, 1024)にブロードキャストできない理由は、形状が正しく整列していないためです。模式的にそれを置くために、私たちは持っている:

weights :   32 
data : 32 x 1024 

我々はdataの第一の軸に整列weightsの最初の軸である軸のみを、整列する必要があります。ですから、ある方法がreshape2Dにあることを発見したので、2番目の軸としてシングルトンの次元になります。我々が持っているでしょう変更されたバージョンで、バック模式的に行く:

weights : 32 x 1 
data : 32 x 1024 

今、形状が揃っていることを、私たちはそれらの要素ごとの操作を行うことができます。

私たちは、明示的にそうように、None/np.newaxisとその新しい軸を導入し、これreshapingを置き換えることができます - さんは、きちんと選択肢を見てみましょう

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

!私たちはそうのように、dataの第一の軸に対してweightsの第一の軸を失うとして、マトリックス乗算は​​を使用してだろう

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

もう一つの方法 -

一つのきちんとして、おそらく直感的な方法は、np.einsumとなります -

weights.dot(data) 
+0

明確で徹底的な答え、ありがとう。私は 'np.einsum'については知らなかった - それは文法に慣れていない人には明らかではないと思われるが、 'np.dot'スタイルは「ちょうど意味をなさない」ものに近づき、うまくコンパクトです。 –

関連する問題