2017-06-02 4 views
1

最初に、私が達成しようとしているのは何らかのデカルト積であるが、NumpyまたはTensorFlowを使用した複数の2D行列の効率的な軸別デカルト積

サイズ[(N、D1)、(N、D​​2)、(N、D​​3)...(N、Dn)]の複数の2D配列がある場合は、

したがって、結果は、最終的な結果が形状(N、D)(D = D1 * D2 * D3 * ... Dn

など)となるように、軸= 1を横切る組合せ生成物となる。

A = np.array([[1,2], 
       [3,4]]) 
B = np.array([[10,20,30], 
       [5,6,7]]) 

cartesian_product([A,B], axis=1) 
>> np.array([[ 1*10, 1*20, 1*30, 2*10, 2*20, 2*30 ] 
      [ 3*5, 3*6, 3*7, 4*5, 4*6, 4*7 ]]) 

とcartesian_productに拡張([A、B、C、D ...]を、軸= 1)

例えば

A = np.array([[1,2], 
       [3,4]]) 
B = np.array([[10,20], 
       [5,6]]) 
C = np.array([[50, 0], 
       [60, 8]]) 
cartesian_product([A,B,C], axis=1) 
>> np.array([[ 1*10*50, 1*10*0, 1*20*50, 1*20*0, 2*10*50, 2*10*0, 2*20*50, 2*20*0] 
      [ 3*5*60, 3*5*8, 3*6*60, 3*6*8, 4*5*60, 4*5*8, 4*6*60, 4*6*8]]) 

Iは、本質的に空(N、D)行列を作成し、提供されたリスト内の各行列のためのforループネスト内の各列のベクトル列方向製品を放送ワーキングソリューションを持っています。配列が大きくなると、明らかに恐ろしいことです!

このためにnumpyまたはテンソルフロー内に既存のソリューションがありますか?潜在的に1つは効率的に並列化できます(テンソルフローは素晴らしいでしょうが、numpyは問題ありません。ベクトルロジックが明確であれば、tfを同等にするのは難しくありません)

私はこれを達成するためにエインサム、テンソルド、メッシュグリッド、またはそれらの組み合わせを使用する必要があります。私は解決策を持っていますが、その解決策は任意の次元配列(ベクトルを意味するように見える)のために働くと言われていますが、https://stackoverflow.com/a/11146645/2123721の単一次元ベクトルに対してのみです。その1つでは、私は.prod(軸= 1)を行うことができますが、これはベクトルに対してのみ有効です。

ありがとうございました!

+0

あなたが保存されているもの、複数の2Dアレイを持つにはどうすればよいですか?配列のリストとして?または、1つの3D配列として? – Divakar

+0

@Divakar現時点では、複数の2D配列は、例[A、B ...]のようにリストにメモリに格納されています。これらは、放送されたドットプロダクトの前のステップの結果である。今のところ、これは大丈夫です。個々にそれらを格納するのはボトルネックではありません。このステージを最適化するための提案がある場合でも、私はすべての耳です! – undercurrent

答えて

1

ここelmentwise乗算のためのアレイのリストから、各ペアの寸法を拡張した後broadcastingを利用して蓄積した方法で繰り返しこれを行うための一つの方法だ -

L = [A,B,C] # list of arrays 
n = L[0].shape[0] 
out = (L[1][:,None]*L[0][:,:,None]).reshape(n,-1) 
for i in L[2:]: 
    out = (i[:,None]*out[:,:,None]).reshape(n,-1) 
+0

素晴らしい!それは完全に動作します(私の現在の方法よりも約10倍速い) – undercurrent

関連する問題