2017-04-27 84 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