2017-05-09 26 views
3

我有兩個多維數組,我們說他們有5個維度的x和y,我想找出x的最後一個元素是最小值的x的值。 要查找索引,我只需使用I=argmin(y,axis=-1),這將返回一個4維索引數組。我應該怎麼做才能找到這些索引的x的值?某種x[I]索引在一個軸上應用了argmin索引的多維數組

+0

2 D ... 4 D?提供一些代碼和一些研究,所以我們可以有一個關於你在說什麼的想法 –

+0

我所擁有的是ax數組的形狀在[87] shape(x) Out [87]:(6,10,10, 5,50)' 和相同尺寸的yy陣列。我想找到的是y的最後一個維度被最小化的x的值。 我做的第一步是'I = argmin(y,axis = -1)',它返回一個索引數組。現在我想知道如何檢查哪些x對應於這些索引 – gian9

+0

@ gian9您可以提供x和y示例以及期望的輸出嗎? – Nuageux

回答

3

方法#1:這基本上是advanced-indexing延伸到5D的情況。爲了讓事情變得更方便一點,我們可以利用開放範圍陣列與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_並因此具有一個通用的函數來處理維度的通用號碼的ndarrays -

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

讓我們用一些樣品隨機值數組和驗證通過直接計算min沿最後軸與y.min(axis=-1)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要保持模糊,可以在末尾附加一個新軸:'ymin [...,None]'和'xmin [...,無]'。 – Divakar

1

使用argmin用1個或2D陣列是相當簡單的,但具有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),每個平面/行的索引。

I[0,0]表示y[i,j,I[i,j]]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]]) 

或縮短,爲:

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

即使2D的方法是相同的:

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數組。