How do I get indices of N maximum values in a NumPy array?

后端 未结 18 1253
长情又很酷
长情又很酷 2020-11-22 04:25

NumPy proposes a way to get the index of the maximum value of an array via np.argmax.

I would like a similar thing, but returning the indexes of the

相关标签:
18条回答
  • 2020-11-22 04:55

    This code works for a numpy 2D matrix array:

    mat = np.array([[1, 3], [2, 5]]) # numpy matrix
     
    n = 2  # n
    n_largest_mat = np.sort(mat, axis=None)[-n:] # n_largest 
    tf_n_largest = np.zeros((2,2), dtype=bool) # all false matrix
    for x in n_largest_mat: 
      tf_n_largest = (tf_n_largest) | (mat == x) # true-false  
    
    n_largest_elems = mat[tf_n_largest] # true-false indexing 
    

    This produces a true-false n_largest matrix indexing that also works to extract n_largest elements from a matrix array

    0 讨论(0)
  • 2020-11-22 04:57

    Three Answers Compared For Coding Ease And Speed

    Speed was important for my needs, so I tested three answers to this question.

    Code from those three answers was modified as needed for my specific case.

    I then compared the speed of each method.

    Coding wise:

    1. NPE's answer was the next most elegant and adequately fast for my needs.
    2. Fred Foos answer required the most refactoring for my needs but was the fastest. I went with this answer, because even though it took more work, it was not too bad and had significant speed advantages.
    3. off99555's answer was the most elegant, but it is the slowest.

    Complete Code for Test and Comparisons

    import numpy as np
    import time
    import random
    import sys
    from operator import itemgetter
    from heapq import nlargest
    
    ''' Fake Data Setup '''
    a1 = list(range(1000000))
    random.shuffle(a1)
    a1 = np.array(a1)
    
    ''' ################################################ '''
    ''' NPE's Answer Modified A Bit For My Case '''
    t0 = time.time()
    indices = np.flip(np.argsort(a1))[:5]
    results = []
    for index in indices:
        results.append((index, a1[index]))
    t1 = time.time()
    print("NPE's Answer:")
    print(results)
    print(t1 - t0)
    print()
    
    ''' Fred Foos Answer Modified A Bit For My Case'''
    t0 = time.time()
    indices = np.argpartition(a1, -6)[-5:]
    results = []
    for index in indices:
        results.append((a1[index], index))
    results.sort(reverse=True)
    results = [(b, a) for a, b in results]
    t1 = time.time()
    print("Fred Foo's Answer:")
    print(results)
    print(t1 - t0)
    print()
    
    ''' off99555's Answer - No Modification Needed For My Needs '''
    t0 = time.time()
    result = nlargest(5, enumerate(a1), itemgetter(1))
    t1 = time.time()
    print("off99555's Answer:")
    print(result)
    print(t1 - t0)
    

    Output with Speed Reports

    NPE's Answer:
    [(631934, 999999), (788104, 999998), (413003, 999997), (536514, 999996), (81029, 999995)]
    0.1349949836730957
    
    Fred Foo's Answer:
    [(631934, 999999), (788104, 999998), (413003, 999997), (536514, 999996), (81029, 999995)]
    0.011161565780639648
    
    off99555's Answer:
    [(631934, 999999), (788104, 999998), (413003, 999997), (536514, 999996), (81029, 999995)]
    0.439760684967041
    
    0 讨论(0)
  • 2020-11-22 05:00

    The following is a very easy way to see the maximum elements and its positions. Here axis is the domain; axis = 0 means column wise maximum number and axis = 1 means row wise max number for the 2D case. And for higher dimensions it depends upon you.

    M = np.random.random((3, 4))
    print(M)
    print(M.max(axis=1), M.argmax(axis=1))
    
    0 讨论(0)
  • 2020-11-22 05:02

    Use:

    from operator import itemgetter
    from heapq import nlargest
    result = nlargest(N, enumerate(your_list), itemgetter(1))
    

    Now the result list would contain N tuples (index, value) where value is maximized.

    0 讨论(0)
  • 2020-11-22 05:03

    I found it most intuitive to use np.unique.

    The idea is, that the unique method returns the indices of the input values. Then from the max unique value and the indicies, the position of the original values can be recreated.

    multi_max = [1,1,2,2,4,0,0,4]
    uniques, idx = np.unique(multi_max, return_inverse=True)
    print np.squeeze(np.argwhere(idx == np.argmax(uniques)))
    >> [4 7]
    
    0 讨论(0)
  • 2020-11-22 05:04

    Use:

    >>> import heapq
    >>> import numpy
    >>> a = numpy.array([1, 3, 2, 4, 5])
    >>> heapq.nlargest(3, range(len(a)), a.take)
    [4, 3, 1]
    

    For regular Python lists:

    >>> a = [1, 3, 2, 4, 5]
    >>> heapq.nlargest(3, range(len(a)), a.__getitem__)
    [4, 3, 1]
    

    If you use Python 2, use xrange instead of range.

    Source: heapq — Heap queue algorithm

    0 讨论(0)
提交回复
热议问题