Numpy: find index of the elements within range

前端 未结 12 2044
盖世英雄少女心
盖世英雄少女心 2020-11-28 23:01

I have a numpy array of numbers, for example,

a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])  

I would like to find all the indexes of the

相关标签:
12条回答
  • 2020-11-28 23:23

    As in @deinonychusaur's reply, but even more compact:

    In [7]: np.where((a >= 6) & (a <=10))
    Out[7]: (array([3, 4, 5]),)
    
    0 讨论(0)
  • 2020-11-28 23:23

    I thought I would add this because the a in the example you gave is sorted:

    import numpy as np
    a = [1, 3, 5, 6, 9, 10, 14, 15, 56] 
    start = np.searchsorted(a, 6, 'left')
    end = np.searchsorted(a, 10, 'right')
    rng = np.arange(start, end)
    rng
    # array([3, 4, 5])
    
    0 讨论(0)
  • 2020-11-28 23:25
    a = np.array([1,2,3,4,5,6,7,8,9])
    b = a[(a>2) & (a<8)]
    
    0 讨论(0)
  • 2020-11-28 23:26
    a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])
    np.argwhere((a>=6) & (a<=10))
    
    0 讨论(0)
  • 2020-11-28 23:27

    Summary of the answers

    For understanding what is the best answer we can do some timing using the different solution. Unfortunately, the question was not well-posed so there are answers to different questions, here I try to point the answer to the same question. Given the array:

    a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])
    

    The answer should be the indexes of the elements between a certain range, we assume inclusive, in this case, 6 and 10.

    answer = (3, 4, 5)
    

    Corresponding to the values 6,9,10.

    To test the best answer we can use this code.

    import timeit
    setup = """
    import numpy as np
    import numexpr as ne
    
    a = np.array([1, 3, 5, 6, 9, 10, 14, 15, 56])
    # we define the left and right limit
    ll = 6
    rl = 10
    
    def sorted_slice(a,l,r):
        start = np.searchsorted(a, l, 'left')
        end = np.searchsorted(a, r, 'right')
        return np.arange(start,end)
    """
    
    functions = ['sorted_slice(a,ll,rl)', # works only for sorted values
    'np.where(np.logical_and(a>=ll, a<=rl))[0]',
    'np.where((a >= ll) & (a <=rl))[0]',
    'np.where((a>=ll)*(a<=rl))[0]',
    'np.where(np.vectorize(lambda x: ll <= x <= rl)(a))[0]',
    'np.argwhere((a>=ll) & (a<=rl)).T[0]', # we traspose for getting a single row
    'np.where(ne.evaluate("(ll <= a) & (a <= rl)"))[0]',]
    
    functions2 = [
       'a[np.logical_and(a>=ll, a<=rl)]',
       'a[(a>=ll) & (a<=rl)]',
       'a[(a>=ll)*(a<=rl)]',
       'a[np.vectorize(lambda x: ll <= x <= rl)(a)]',
       'a[ne.evaluate("(ll <= a) & (a <= rl)")]',
    ]
    

    Results

    The results are reported in the following plot. On the top the fastest solutions. If instead of the indexes you want to extract the values you can perform the tests using functions2 but the results are almost the same.

    0 讨论(0)
  • 2020-11-28 23:27

    You can use np.clip() to achieve the same:

    a = [1, 3, 5, 6, 9, 10, 14, 15, 56]  
    np.clip(a,6,10)
    

    However, it holds the values less than and greater than 6 and 10 respectively.

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