2017-04-27 83 views
2

我有以下X numpy數組。我想用X [i]和陣列的三個最小X [i] [3]值創建一個數組。返回numpy數組的最小X數並保持順序

array([[ 2, 356, 1, 0.7], 
     [ 3, 356, 1, 5], 
     [ 3, 357, 1, 3], 
     [ 4, 355, 1, 0.1], 
     [ 4, 356, 1, 16], 
     [ 4, 357, 1, 2]]) 

結果應該是這樣的:

array([[ 2, 356, 1, 0.7], 
     [ 4, 355, 1, 0.1], 
     [ 4, 357, 1, 2]]) 

回答

7

這裏有一個方法 -

X[np.sort(X[:,3].argsort()[:3])] 

基本上,我們使用argsort得到分類指標,選擇前三種爲最低的三個元素。我們將用這些索引爲輸出索引數組。爲了在輸入數組中保持順序,請在索引之前對這些索引進行排序。

採樣運行 -

In [148]: X 
Out[148]: 
array([[ 2.00e+00, 3.56e+02, 1.00e+00, 7.00e-01], 
     [ 3.00e+00, 3.56e+02, 1.00e+00, 5.00e+00], 
     [ 3.00e+00, 3.57e+02, 1.00e+00, 3.00e+00], 
     [ 4.00e+00, 3.55e+02, 1.00e+00, 1.00e-01], 
     [ 4.00e+00, 3.56e+02, 1.00e+00, 1.60e+01], 
     [ 4.00e+00, 3.57e+02, 1.00e+00, 2.00e+00]]) 

In [149]: X[np.sort(X[:,3].argsort()[:3])] 
Out[149]: 
array([[ 2.00e+00, 3.56e+02, 1.00e+00, 7.00e-01], 
     [ 4.00e+00, 3.55e+02, 1.00e+00, 1.00e-01], 
     [ 4.00e+00, 3.57e+02, 1.00e+00, 2.00e+00]]) 

出於性能,我們可以用np.argpartition。所以,X[:,3].argsort()[:3]可以替換np.argpartition(X[:,3],3)[:3]argpartition,因爲它的實施方式爲我們提供了對應於最低3元素的指數,而不一定是按照從最低到次低到次低的順序。但是沒關係,因爲我們稍後會對這些索引進行排序,以保持輸入數組中的順序(前面討論過)。在性能提升的建議

計時 - 上

In [164]: X = np.random.rand(100000,4) 

In [165]: np.sort(X[:,3].argsort()[:3]) 
Out[165]: array([ 9950, 69008, 76552]) 

In [166]: np.sort(np.argpartition(X[:,3],3)[:3]) 
Out[166]: array([ 9950, 69008, 76552]) 

In [167]: %timeit np.sort(X[:,3].argsort()[:3]) 
100 loops, best of 3: 7.59 ms per loop 

In [168]: %timeit np.sort(np.argpartition(X[:,3],3)[:3]) 
1000 loops, best of 3: 290 µs per loop 
+2

恭喜100K♪(*^^·)ノ⌒オメデト☆你的100K – EdChum

+0

@EdChum恭喜了。史詩! :) –

+0

@MosesKoledoye謝謝 – EdChum