2016-10-31 77 views
1

我想從suitCounts中選擇maxsuit中指定的第n個元素。我確實廣播了maxsuit數組,所以我得到了一個結果,但不是所需的結果。任何建議,我在做什麼概念錯誤,表示讚賞。我不明白np.choose(self.maxsuit[:,:,None]-1, self.suitCounts)的結果,這不是我正在尋找的結果。np.choose廣播後沒有給出想要的結果

>>> self.maxsuit 
Out[38]: 
array([[3, 3], 
     [1, 1], 
     [1, 1]], dtype=int64) 

>>> self.maxsuit[:,:,None]-1 
Out[33]: 
array([[[2], 
     [2]], 

     [[0], 
     [0]], 

     [[0], 
     [0]]], dtype=int64) 
>>> self.suitCounts 
Out[34]: 
array([[[2, 1, 3, 0], 
     [1, 0, 3, 0]], 

     [[4, 1, 2, 0], 
     [3, 0, 3, 0]], 

     [[2, 2, 0, 0], 
     [1, 1, 1, 0]]]) 
>>> np.choose(self.maxsuit[:,:,None]-1, self.suitCounts) 
Out[35]: 
array([[[2, 2, 0, 0], 
     [1, 1, 1, 0]], 

     [[2, 1, 3, 0], 
     [1, 0, 3, 0]], 

     [[2, 1, 3, 0], 
     [1, 0, 3, 0]]]) 

期望的結果將是:

[[3,3],[4,3],[2,1]] 

回答

1

你可以使用advanced-indexing的廣播方式索引到數組,像這樣 -

In [415]: val  # Data array 
Out[415]: 
array([[[2, 1, 3, 0], 
     [1, 0, 3, 0]], 

     [[4, 1, 2, 0], 
     [3, 0, 3, 0]], 

     [[2, 2, 0, 0], 
     [1, 1, 1, 0]]]) 

In [416]: idx  # Indexing array 
Out[416]: 
array([[3, 3], 
     [1, 1], 
     [1, 1]]) 

In [417]: m,n = val.shape[:2] 

In [418]: val[np.arange(m)[:,None],np.arange(n),idx-1] 
Out[418]: 
array([[3, 3], 
     [4, 3], 
     [2, 1]]) 

有點清潔的方式與np.ogrid使用開放式陣列 -

In [424]: d0,d1 = np.ogrid[:m,:n] 

In [425]: val[d0,d1,idx-1] 
Out[425]: 
array([[3, 3], 
     [4, 3], 
     [2, 1]]) 
+0

這是偉大的,只是想知道,有沒有也是一種方式與np.choose做呢? – Nickpick

+0

@nickpick對不起,我沒有使用'np.choose',所以不能幫助你。我只是喜歡直接做這件事。 – Divakar

+0

有道理。你似乎是一個花哨索引專家。你有什麼文獻可以推薦? – Nickpick

0

這是我可以選擇

In [23]: np.choose([[1,2,0],[1,2,0]], suitcounts[:,:,:3]) 
Out[23]: 
array([[4, 2, 3], 
     [3, 1, 3]]) 

choose做的最好的喜歡,我們使用數組列表,而不是單一的一個。它應該防止濫用。所以,問題可以被寫爲:

In [24]: np.choose([[1,2,0],[1,2,0]], [suitcounts[0,:,:3], suitcounts[1,:,:3], suitcounts[2,:,:3]]) 
Out[24]: 
array([[4, 2, 3], 
     [3, 1, 3]]) 

的想法是選擇從3子陣列的項目,基於索引陣列等上:

In [25]: np.array([[1,2,0],[1,2,0]]) 
Out[25]: 
array([[1, 2, 0], 
     [1, 2, 0]]) 

輸出將在形狀索引陣列相匹配。 choise陣列也具有匹配的形狀,因此我使用[...,:3]

對於第一列

值被從suitcounts[1,:,:3]選擇,對於第二列從suitcounts[2...]

choose被限制爲32點的選擇;這是廣播機制強加的限制。

說起廣播的,我可以簡化表達

In [26]: np.choose([1,2,0], suitcounts[:,:,:3]) 
Out[26]: 
array([[4, 2, 3], 
     [3, 1, 3]]) 

該廣播[1,2,0]到子陣列的2×3的形狀相匹配。

我可以重新排序的列得到目標順序:

In [27]: np.choose([0,1,2], suitcounts[:,:,[2,0,1]]) 
Out[27]: 
array([[3, 4, 2], 
     [3, 3, 1]]) 
相關問題