2016-04-10 17 views
1

私は形状がNumPyの配列(2,76020,2)を持っています。基本的には、それぞれ76020行を含む2つの列で構成され、各行には2つのエントリがあります。スカラーでNumPy配列を掛ける

それぞれの列に異なる重み、たとえば13と列25とを掛けたいとします。たとえば:

m = 
[3,4][5,8] 
[1,2][2,2] 

a = [3,5] 

私がしたい:

[9,12][25,40] 
[3,6][10,10] 

は、私はちょうどメートルの* aを掛けることができると思ったが、それは代わりに私を与える:

[9,20][15,40] 
[3,10][6,10] 

は、どのように私はこの乗算を書くことができますか?

+1

ディメンションを区別するために、このようなコードをテストするとよい考えです。あなたのテスト 'm'は形'(2,2,2) 'です。これは「列」の次元です。それが '(3,10,2) 'か、または別の次元のものであれば、どの軸(2つの要素を持つ)がどの軸に適用できるかどうかを一目で分かります。 – hpaulj

+0

はい、あなたは正しいです! – user

答えて

3

それはbroadcastingの問題です:あなたは、第二の、ここで、乗算する寸法を揃える必要があります@のB.Mとして

m = array(
[[[3,4],[5,8]], 
[[1,2],[2,2]]]) 
a = array([3,5]) 
print(a[None,:,None].shape, m*a[None,:,None]) 
""" 
(1, 2, 1) 

[[[ 9 12] 
    [25 40]] 

[[ 3 6] 
    [10 10]]] 
""" 
+0

実際に私はあなたのアイデアを踏襲し、m * a [:、None、None]とし、それがうまくいった。だから何も指定しなければ、デフォルトは何ですか? – user

+0

私はそれがデータ表現の問題だと思います。私はあなたの例のために解決策を挙げていますが、おそらく私のブレースは良いものではありません。あなたの(2,76020,2)データでは、もちろん最初の次元で整列する必要があるので、m * a [:、None、None]は良い解です。 –

+0

はい、何も指定しなければ何が起こるのか不思議に思っていました。 numpyはデフォルトでどのようにデータを整列させますか? – user

2

。これは「array broadcasting」の問題です(彼の答えの背後にある考え方は正しいですが、私は彼とOPの寸法が正しく一致していないと思います。)

>>> m = np.array([[[3,4],[5,8]],[[1,2],[2,2]]]) 
>>> print(m) 
[[[3 4] 
    [5 8]] 

[[1 2] 
    [2 2]]] 
>>> print(m.shape) 
(2, 2, 2) 
>>> a = np.array([3,5]) 
>>> print(a.shape) 
(2,) 

我々はmaの形状が一致する必要があるので、我々は「放送」する必要がありますa正しい形状に:このように

>>> print(a[:, np.newaxis, np.newaxis].shape) 
(2, 1, 1) 
>>> b = a[:, np.newaxis, np.newaxis] * m 
>>> print(b) 
[[[ 9 12] 
    [15 24]] 

[[ 5 10] 
    [10 10]]] 

aの最初の寸法が保存され、そしてmの最初の次元の各要素にマップします。しかし、mの他の2つの次元に「ブロードキャスト」するために作成された2つの新しい次元( '軸')もあります。

注:np.newaxisは(文字通り)Noneですが、同じ効果があります。前者は何が起こっているのかを理解するために読みやすくなっています。さらに、標準的な用語でいうと、第1の次元(軸)は一般に「行」と呼ばれ、第2の軸は「列」と呼ばれます。

1

あなたの説明は基本的には、76020個の行をそれぞれ含む二つの列で構成されている

曖昧であり、各行は2つのエントリを有しています。

(2,76020,2)のうち、2は、どのエントリですか?

私はm*a[None,None,:]と同じだそれ

In [8]: m 
Out[8]: 
array([[[3, 4], 
     [5, 8]], 

     [[1, 2], 
     [2, 2]]]) 


In [9]: m*a 
Out[9]: 
array([[[ 9, 20], 
     [15, 40]], 

     [[ 3, 10], 
     [ 6, 10]]]) 

(その表示も曖昧である)あなたのmがあると信じています。放送するとき、numpyは必要に応じて最初に自動的に次元を追加します。または、反復:

In [6]: m[:,:,0]*3 
Out[6]: 
array([[ 9, 15], 
     [ 3, 6]]) 

In [7]: m[:,:,1]*5 
Out[7]: 
array([[20, 40], 
     [10, 10]]) 

m(2,2,2)形状であるので、我々はオフの手はaを掛けることになっている軸伝えることはできません。

受け入れ答えによると、あなたは中央の軸

In [16]: m*a[None,:,None] 
Out[16]: 
array([[[ 9, 12], 
     [25, 40]], 

     [[ 3, 6], 
     [10, 10]]]) 

しかし、何m場合、形状が(2,3,2)だったに沿って掛けたいですか? aを3つの値

In [17]: m=np.array([[[3,4],[5,8],[0,0]],[[1,2],[2,2],[1,1]]]) 

In [18]: m*a[None,:,None] 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-18-f631c33646b7> in <module>() 
----> 1 m*a[None,:,None] 

ValueError: operands could not be broadcast together with shapes (2,3,2) (1,2,1) 

代替放送の作業今

In [19]: m*a[:,None,None] 
Out[19]: 
array([[[ 9, 12], 
     [15, 24], 
     [ 0, 0]], 

     [[ 5, 10], 
     [10, 10], 
     [ 5, 5]]]) 

In [20]: m*a[None,None,:] 
Out[20]: 
array([[[ 9, 20], 
     [15, 40], 
     [ 0, 0]], 

     [[ 3, 10], 
     [ 6, 10], 
     [ 3, 5]]]) 

mは異なる寸法を有する場合、例えばを有する必要があろう(3,1000,2)では、軸を使って2要素のウェイト配列を扱うことができます。

+0

修正された答えはm * a [:、None、None]です。私は正しい答えとしてそれをチェックしました。なぜなら、そうではありませんが、この問題を解決する方法を教えてくれたからです。しかし、非常に網羅的で、あなたの答えにも感謝し、次回より良い質問を書く方法を教えてください。 +1 – user