location of array of values in numpy array

后端 未结 2 1862
春和景丽
春和景丽 2021-01-21 09:48

Here is a small code to illustrate the problem.

A = array([[1,2], [1,0], [5,3]])
f_of_A = f(A)   # this is precomputed and expensive


values = array([[1,2], [1,         


        
相关标签:
2条回答
  • 2021-01-21 09:58

    You can use np.in1d over a view of your original array with all coordinates collapsed into a single variable of dtype np.void:

    import numpy as np
    
    A = np.array([[1,2], [1,0], [5,3]])
    values = np.array([[1,2], [1,0]])
    
    # Make sure both arrays are contiguous and have common dtype
    common_dtype = np.common_type(A, values)
    a = np.ascontiguousarray(A, dtype=common_dtype)
    vals = np.ascontiguousarray(values, dtype=common_dtype)
    
    a_view = A.view((np.void, A.dtype.itemsize*A.shape[1])).ravel()
    values_view = values.view((np.void,
                               values.dtype.itemsize*values.shape[1])).ravel()
    

    Now each item of a_view and values_view is all coordinates for one point packed together, so you can do whatever 1D magic you would use. I don't see how to use np.in1d to find indices though, so I would go the np.searchsorted route:

    sort_idx = np.argsort(a_view)
    locations = np.searchsorted(a_view, values_view, sorter=sort_idx)
    locations = sort_idx[locations]
    
    >>> locations
    array([0, 1], dtype=int64)
    
    0 讨论(0)
  • 2021-01-21 10:12

    Okay, this is what I came up with.

    To find the value of one multi-dimensional index, let's say ii = np.array([1,2]), we can do:

    n.where((A == ii).all(axis=1))[0]
    

    Let's break this down, we have A == ii, which will give element-wise comparisons with ii for each row of A. We want an entire row to be true, so we add .all(axis=1) to collapse them. To find where these indices happen, we plug this into np.where and get the first value of the tuple.

    Now, I don't have a fast way to do this with multiple indices yet (although I have a feeling there is one). However, this will get the job done:

    np.hstack([np.where((A == values[i]).all(axis=1))[0] for i in xrange(len(values))])
    

    This basically just calls the above, for each value of values, and concatenates the result.

    Update:

    Here is for the multi-dimensional case (all in one go, should be fairly fast):

    np.where((np.expand_dims(A, -1) == values.T).all(axis=1).any(axis=1))[0]
    
    0 讨论(0)
提交回复
热议问题