2016-08-02 9 views
4

私は2つのNumpy配列xの形状が(m, i)yで、形が(m, j)であるため(行数が同じです) xの各列にの各列を要素ごとに掛けて、結果が形が(m, i*j)になるようにしたいと思います。2D配列の各列と別の2D配列の各列を掛け合わせます

例:

array([[1, 1, 0], 
     [0, 1, 1], 
     [1, 1, 1], 
     [0, 0, 1], 
     [0, 1, 1], 
     [0, 0, 1], 
     [0, 0, 0], 
     [1, 0, 0], 
     [1, 0, 0], 
     [0, 1, 0]]) 

y

import numpy as np 

np.random.seed(1) 
x = np.random.randint(0, 2, (10, 3)) 
y = np.random.randint(0, 2, (10, 2)) 

これは、次の2つのアレイx作成

array([[0, 0], 
     [1, 1], 
     [1, 1], 
     [1, 0], 
     [0, 0], 
     [1, 1], 
     [1, 1], 
     [1, 1], 
     [0, 1], 
     [1, 0]]) 

を今結果がなければならない:

array([[0, 0, 0, 0, 0, 0], 
     [0, 0, 1, 1, 1, 1], 
     [1, 1, 1, 1, 1, 1], 
     [0, 0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 1, 1], 
     [0, 0, 0, 0, 0, 0], 
     [1, 1, 0, 0, 0, 0], 
     [0, 1, 0, 0, 0, 0], 
     [0, 0, 1, 0, 0, 0]]) 

現在、私はxyの列にわたって2つのネストされたループでこの操作を実装しました。しかし

def _mult(x, y): 
    r = [] 
    for xc in x.T: 
     for yc in y.T: 
      r.append(xc * yc) 
    return np.array(r).T 

、私はもっとエレガントな解決策が存在しなければならないことをかなり確信している私ができます思いつかないようだ。

答えて

6

使用NumPy broadcasting -

(y[:,None]*x[...,None]).reshape(x.shape[0],-1) 

説明

入力として、私たちは持っている - y[:,None]

y : 10 x 2 
x : 10 x 3 

は、我々はこのように、既存の2暗くなり間の新しい軸を導入していますその配列バージョン3Dを作成します。これにより、最初の軸が3Dのバージョンの最初の軸として保持され、3番目の軸として2番目の軸が押し出されます。

x[...,None]では、既存の2つのディムを最初の2つのディムとして押し上げ、3Dアレイバージョンにすることで、新しい軸を最後に導入します。

新しい軸の導入により、要約すると、我々は持っている - y[:,None]*x[...,None]

y : 10 x 1 x 2 
x : 10 x 3 x 1 

を、(10,3,2)の形状を持つ出力配列で、その結果、yxの両方のためのbroadcastingがあるでしょう。形状(10,6)の最終出力配列に到達するには、最後の2つの軸をその変形とマージする必要があります。

+0

"複雑な"ハックですが、非常に簡潔です! +1 –

+0

ここに説明を追加できますか?簡潔ですが説明はできません。 – kmario23

+0

@ kmario23いくつかの説明が追加されました。 – Divakar