Python: intersection indices numpy array

前端 未结 4 431
走了就别回头了
走了就别回头了 2020-12-24 05:53

How can I get the indices of intersection points between two numpy arrays? I can get intersecting values with intersect1d:

import numpy as np

a         


        
相关标签:
4条回答
  • 2020-12-24 06:11

    For Python >= 3.5, there's another solution to do so

    Other Solution

    Let we go through this step by step.

    Based on the original code from the question

    import numpy as np
    
    a = np.array(range(11))
    b = np.array([2, 7, 10])
    inter = np.intersect1d(a, b)
    

    First, we create a numpy array with zeros

    c = np.zeros(len(a))
    print (c)
    

    output

    >>> [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]
    

    Second, change array value of c using intersect index. Hence, we have

    c[inter] = 1
    print (c)
    

    output

    >>>[ 0.  0.  1.  0.  0.  0.  0.  1.  0.  0.  1.]
    

    The last step, use the characteristic of np.nonzero(), it will return exactly the index of the non-zero term you want.

    inter_with_idx = np.nonzero(c)
    print (inter_with_idx)
    

    Final output

    array([ 2, 7, 10])
    

    Reference

    [1] numpy.nonzero

    0 讨论(0)
  • 2020-12-24 06:15

    You could use the boolean array produced by in1d to index an arange. Reversing a so that the indices are different from the values:

    >>> a[::-1]
    array([10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0])
    >>> a = a[::-1]
    

    intersect1d still returns the same values...

    >>> numpy.intersect1d(a, b)
    array([ 2,  7, 10])
    

    But in1d returns a boolean array:

    >>> numpy.in1d(a, b)
    array([ True, False, False,  True, False, False, False, False,  True,
           False, False], dtype=bool)
    

    Which can be used to index a range:

    >>> numpy.arange(a.shape[0])[numpy.in1d(a, b)]
    array([0, 3, 8])
    >>> indices = numpy.arange(a.shape[0])[numpy.in1d(a, b)]
    >>> a[indices]
    array([10,  7,  2])
    

    To simplify the above, though, you could use nonzero -- this is probably the most correct approach, because it returns a tuple of uniform lists of X, Y... coordinates:

    >>> numpy.nonzero(numpy.in1d(a, b))
    (array([0, 3, 8]),)
    

    Or, equivalently:

    >>> numpy.in1d(a, b).nonzero()
    (array([0, 3, 8]),)
    

    The result can be used as an index to arrays of the same shape as a with no problems.

    >>> a[numpy.nonzero(numpy.in1d(a, b))]
    array([10,  7,  2])
    

    But note that under many circumstances, it makes sense just to use the boolean array itself, rather than converting it into a set of non-boolean indices.

    Finally, you can also pass the boolean array to argwhere, which produces a slightly differently-shaped result that's not as suitable for indexing, but might be useful for other purposes.

    >>> numpy.argwhere(numpy.in1d(a, b))
    array([[0],
           [3],
           [8]])
    
    0 讨论(0)
  • 2020-12-24 06:15

    If you need to get unique values as given by intersect1d:

    import numpy as np
    
    a = np.array([range(11,21), range(11,21)]).reshape(20)
    b = np.array([12, 17, 20])
    print(np.intersect1d(a,b))
    #unique values
    
    inter = np.in1d(a, b)
    print(a[inter])
    #you can see these values are not unique
    
    indices=np.array(range(len(a)))[inter]
    #These are the non-unique indices
    
    _,unique=np.unique(a[inter], return_index=True)
    
    uniqueIndices=indices[unique]
    #this grabs the unique indices
    
    print(uniqueIndices)
    print(a[uniqueIndices])
    #now they are unique as you would get from np.intersect1d()
    

    Output:

    [12 17 20]
    [12 17 20 12 17 20]
    [1 6 9]
    [12 17 20]
    
    0 讨论(0)
  • 2020-12-24 06:17
    indices = np.argwhere(np.in1d(a,b))
    
    0 讨论(0)
提交回复
热议问题