2017-05-09 12 views
3

私は2つの多次元配列を持っています。それらの両方を5次元でxとyとし、yの最後の成分が最小であるxの値を探します。 インデックスを検索するには、私はI=argmin(y,axis=-1)を使用します。これは私にインデックスの4次元配列を返します。それらのインデックスのxの値を見つけるにはどうすればよいですか?ある種のx[I]一つの軸に沿ってargminインデックスが適用された多次元配列のインデックス付け

+0

2 D ... 4 D?あなたが話していることについて私たちが考えていることができるようにいくつかのコードといくつかの研究を提供しています –

+0

私が持っているものは、形状の軸配列です[87]形(x) Out [87]:(6,10,10、 5,50) ' と同じ次元の配列です。私が見つけたいのは、yの最後の次元が最小化されるxの値です。 私が行う最初のステップは、私にインデックスの配列を返す 'I = argmin(y、axis = -1)'です。ここでどのxがそれらのインデックスに対応しているかチェックする方法を知りたいです – gian9

+0

@ gian9 xとyの例と希望の出力を提供できますか? – Nuageux

答えて

3

アプローチ#1:これは基本的にadvanced-indexing5Dに拡張したものです。物事はもう少し便利にするために、我々はnp.ogridでオープンレンジアレイの使用を行い、その後、advanced-indexingを実行し、そのようにすることができます -

d0,d1,d2,d3,d4 = x.shape 
s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3] 
ymin = y[s0,s1,s2,s3,I] 
xmin = x[s0,s1,s2,s3,I] 

アプローチ#2:私たちは、マージして、それを少し短くすることができますnp.ix_ひいてはとの最初の2つのステップは、次元の一般的な数のndarraysを処理するための汎用的な機能を持っている -

indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,) 
ymin = y[indxs] 
xmin = x[indxs] 

さんが直接と最後の軸に沿ってminを計算することによって、いくつかのサンプルのランダムな数値の配列を使用して検証してみましょうすなわちy.min(-1)提案符号のインデックス付き値yminに対してそれを比較 -

In [117]: x = np.random.randint(0,9,(3,4,5,6,7)) 
    ...: y = np.random.randint(0,9,(3,4,5,6,7)) 
    ...: I = np.argmin(y,axis=-1) 
    ...: 

In [118]: d0,d1,d2,d3,d4 = x.shape 
    ...: s0,s1,s2,s3 = np.ogrid[:d0,:d1,:d2,:d3] 
    ...: ymin = y[s0,s1,s2,s3,I] 
    ...: xmin = x[s0,s1,s2,s3,I] 
    ...: 

In [119]: np.allclose(y.min(-1), ymin) 
Out[119]: True 

In [120]: indxs = np.ix_(*[np.arange(i) for i in x.shape[:-1]]) + (I,) 
    ...: ymin = y[indxs] 
    ...: xmin = x[indxs] 
    ...: 

In [121]: np.allclose(y.min(-1), ymin) 
Out[121]: True 
+0

しかし、このプロセスでは次元は保持されません、間違っていますか?配列を扱い易いように次元を保持することが望ましいでしょう – gian9

+0

@ gian9 dimを維持するために、最後に新しい軸を追加することができます: 'ymin [...、None]'と 'xmin [...、なし]。 – Divakar

1

1つのまたは2Dアレイとargminを使用することはかなり簡単であるが、3以上で、マッピングは理解することが困難である。

In [332]: y=np.arange(24) 
In [333]: np.random.shuffle(y) 
In [334]: y=y.reshape(2,3,4) 
In [335]: y 
Out[335]: 
array([[[19, 12, 9, 21], 
     [ 8, 13, 20, 17], 
     [22, 11, 5, 1]], 

     [[ 7, 2, 23, 16], 
     [ 0, 10, 6, 4], 
     [14, 18, 15, 3]]]) 

In [338]: I = np.argmin(y, axis=-1) 
In [339]: I 
Out[339]: 
array([[2, 0, 3], 
     [1, 0, 3]], dtype=int32) 
In [340]: np.min(y, axis=-1) 
Out[340]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

結果は(2,3)であり、各プレーン/行に1つのインデックスがあります。

I[0,0]は、i,j行の最小値がy[i,j,I[i,j]]であることを意味します。

だから我々はi,jペアリング

In [345]: i,j = np.ix_(np.arange(2), np.arange(3)) 
In [346]: i 
Out[346]: 
array([[0], 
     [1]]) 
In [347]: j 
Out[347]: array([[0, 1, 2]]) 

In [349]: y[i,j,I[i,j]] 
Out[349]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

かにそれを短縮することを生成するための方法が必要です。でも、2dが

In [350]: y[i,j,I] 
Out[350]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

は、方法は同じである:

In [360]: z=y[:,:,1] 
In [361]: z 
Out[361]: 
array([[12, 13, 11], 
     [ 2, 10, 18]]) 
In [362]: idx=np.argmin(z, axis=-1) 
In [363]: idx 
Out[363]: array([2, 0], dtype=int32) 
In [364]: z[[0,1], idx]  # index the 1st dim with range 
Out[364]: array([11, 2]) 

mgridを使用することが容易プロセスを視覚化するためになるかもしれない:ここで

In [378]: i,j =np.mgrid[0:2,0:3] 
In [379]: i 
Out[379]: 
array([[0, 0, 0], 
     [1, 1, 1]]) 
In [380]: j 
Out[380]: 
array([[0, 1, 2], 
     [0, 1, 2]]) 
In [381]: y[i, j, I] 
Out[381]: 
array([[9, 8, 1], 
     [2, 0, 3]]) 

ij形状にIと一致する(2,3)アレイです。一緒に3つの配列はyから要素の(2,3)配列を選択します。

ix_およびogridは、同等のopenアレイを生成するだけです。

関連する問題