返回numpy数组的最小X数并保持顺序

时间:2017-04-27 12:24:30

标签: python numpy

我有以下X numpy数组。我想用X [i]创建一个数组,其中包含数组的三个最小X [i] [3]值。

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]])

1 个答案:

答案 0 :(得分:7)

这是一种方法 -

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]]) 来获取排序的索引,为最低的三个元素选择前三个。我们将使用这些索引为数组索引输出。要保持输入数组中的顺序,请在索引之前对这些索引进行排序。

示例运行 -

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

为了提高性能,我们可以使用np.argpartition。因此,np.argpartition(X[:,3],3)[:3]可以替换为argpartition3因为它的实现方式为我们提供了与最低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 元素相对应的索引,而不一定是从最低到第二低到第三低的顺序。但那没关系,因为我们稍后会对这些索引进行排序,以保持输入数组中的顺序(前面讨论过)。

关于绩效提升建议的时间 -

public boolean isPair() {
    String[] values = new String[5];
    int counter = 0;    

    //Put each cards numeric value into array
    for(int i = 0; i < cards.length; i++){
        values[i] = cards[i].toString();
    }

    //Loop through the values. Compare each value to all values
    //If exactly two matches are made - return true
    for(int j = 0; j < values.length; j++){
        for(int k = 0; k < cards.length; k++){
            if(values[j].equals(cards[k].toString()))
                counter++;
            if(counter == 2)
                return true;

        }
        counter = 0;
    }

    return false;  
}