2017-03-14 9 views
1

の1次元配列を指定して3次元アレイからの2Dアレイの作成、X、インデックスのセット[I、J]I 、J < N、I形状の配列を取得しようとしている(2、m)の最初の配列がインデックスである [0、i]はと二番目の配列は、インデックス[1、j]はであります。これは、形状の配列(b、n、m)と長さbの一連のインデックスに一般化するためのテストケースです。ベクトル化形状<em>(2、n、m)は</em>の配列を指定指数

明らかにこの操作の選択肢はnp.chooseですが、これは予想外の動作です。最初の配列の行iと、2番目の配列の行jをペアにしたいとします。しかし、np.chooseを使用する場合([I、J]を、X)、インデックスアレイから np.choose対最初カラムアレイから2列目とを有するIj(以下のコードで見ることができます)形状の配列を取得する(n、m)。明らかにこのタスクはforループを使って簡単に実行できますが、ユースケース(反復が禁止されているテンソルのカスタム関数としてKeras内にあるため)ではできません。 Kerasのバックエンド関数またはNumpyを使用して、この操作をベクトル化した方法がありますか?私は現在、これを行うために "マップ"を使用して見て、私はそれを把握する場合は自分の答えで更新されます。

>>> import numpy as np 
>>> x = np.random.rand(2,4,2) 
>>> choices = [3,1] 
>>> np.choose(choices,x) 
    ValueError: invalid entry in choice array 
>>> np.choose([0,0],x) 
    #Returns an array with x[0,:,0] and x[0,:,1] in shape(4,2) 
+0

ループコードはありますか? – Divakar

+0

@Divakarはい、それは実行している全体的な作業です(「n」個の個別softmax出力を含むバッチ「b」の最大確率出力を見つけること)。これは、その関数のベクトル化の最後のステップです。全体的な機能のコードも提供する必要がありますか?現時点では無関係だと思われますが、ここで何が起こっているのか、もう少し具体的な文脈を提供すると思います。 – AGentleRose

答えて

1

IIUC、あなたがadvanced indexingを使用することができます。ここでは

はnp.chooseが(2、n、m)は配列の処理方法、あなたを示すコードスニペットです。例の場合:

import numpy as np 
x = np.random.randint(0,10,(2,4,3)) 

xです:今

[[[0 4 1] 
    [8 8 1] 
    [3 3 6] 
    [4 7 8]] 

[[7 1 2] 
    [5 9 9] 
    [0 4 0] 
    [7 8 3]]] 

x[[0,1],[3,1],:]は次のとおりです。

[[4 7 8] 
[5 9 9]] 

これは(b,m,n)問題に拡張することができます。

import numpy as np 
x = np.random.randint(0,10,(100,200,300)) 
choices= np.random.randint(0,200,(100)) 

def loop(): 
    res=np.empty((100,300),int) 
    for i in range(100): 
     res[i]=x[i,choices[i]] 
    return res  

そして、いくつかのパフォーマンステスト:タスク (抽出)メモリ配置を利用することはできませんので

In [30]: %timeit loop() 
10000 loops, best of 3: 140 µs per loop 

In [31]: %timeit x[arange(100),choices,:] 
10000 loops, best of 3: 23.7 µs per loop 

ここでインデックス方法は、ループよりもわずか6倍高速です。

最後に、ジャストインタイムコンパイルを使用してloop2=numba.njit(loop)でループを強化することができます。

In [32]: %timeit loop2() 
10000 loops, best of 3: 32 µs per loop 

これは、インデックス方法が最適であることを示しています。

+0

これはベクトル化されていません - もしあなたがshape(b、4,3)のランダムな配列を与えられているなら、このメソッドを使うためにインデックスのリスト(長さがbです)を反復しなければなりません。 また、x [0,1]にインデックスを作成しようとすると結果が[8,8,1]ではなく、[3,1]は範囲外のエラーを出すべきではありませんか? – AGentleRose

+0

いいえ、[0,3、:]と[1,1、:]でインデックス付けされた配列を返します。 x [a、b、:]] [x [a0、b0、:]、x [a1、b1、:]など] –

+0

これは意味があります。しかし、もしあなたが "選択肢"のインデックスの配列を与えられていれば、単にx [choices ,:]を呼び出すことはできません。あなたのコードが機能するためには、x [choices [0]、choices [1]、:](b = 2の場合)を呼び出すことによって、 "選択肢"を反復処理する必要があります。反復を避け、bが任意である一般的な解を持つ必要があります。 – AGentleRose

関連する問題