【笔记】np.argsort(x , axis=-1) && np.take_along_axis(x,np.argsort(x,axis=-1),axis=-1) : 使用索引对多维数组排序

附:tensor 排序

注1:

注2:

@array_function_dispatch(_argsort_dispatcher)
def argsort(a, axis=-1, kind=None, order=None):
    """
    Returns the indices that would sort an array.

    Perform an indirect sort along the given axis using the algorithm specified
    by the `kind` keyword. It returns an array of indices of the same shape as
    `a` that index data along the given axis in sorted order.

    Parameters
    ----------
    a : array_like
        Array to sort.
    axis : int or None, optional
        Axis along which to sort.  The default is -1 (the last axis). If None,
        the flattened array is used.
    kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
        Sorting algorithm. The default is 'quicksort'. Note that both 'stable'
        and 'mergesort' use timsort under the covers and, in general, the
        actual implementation will vary with data type. The 'mergesort' option
        is retained for backwards compatibility.

        .. versionchanged:: 1.15.0.
           The 'stable' option was added.
    order : str or list of str, optional
        When `a` is an array with fields defined, this argument specifies
        which fields to compare first, second, etc.  A single field can
        be specified as a string, and not all fields need be specified,
        but unspecified fields will still be used, in the order in which
        they come up in the dtype, to break ties.

    Returns
    -------
    index_array : ndarray, int
        Array of indices that sort `a` along the specified `axis`.
        If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`.
        More generally, ``np.take_along_axis(a, index_array, axis=axis)``
        always yields the sorted `a`, irrespective of dimensionality.

    See Also
    --------
    sort : Describes sorting algorithms used.
    lexsort : Indirect stable sort with multiple keys.
    ndarray.sort : Inplace sort.
    argpartition : Indirect partial sort.
    take_along_axis : Apply ``index_array`` from argsort
                      to an array as if by calling sort.

    Notes
    -----
    See `sort` for notes on the different sorting algorithms.

    As of NumPy 1.4.0 `argsort` works with real/complex arrays containing
    nan values. The enhanced sort order is documented in `sort`.

    Examples
    --------
    One dimensional array:

    >>> x = np.array([3, 1, 2])
    >>> np.argsort(x)
    array([1, 2, 0])

    Two-dimensional array:

    >>> x = np.array([[0, 3], [2, 2]])
    >>> x
    array([[0, 3],
           [2, 2]])

    >>> ind = np.argsort(x, axis=0)  # sorts along first axis (down)
    >>> ind
    array([[0, 1],
           [1, 0]])
    >>> np.take_along_axis(x, ind, axis=0)  # same as np.sort(x, axis=0)
    array([[0, 2],
           [2, 3]])

    >>> ind = np.argsort(x, axis=1)  # sorts along last axis (across)
    >>> ind
    array([[0, 1],
           [0, 1]])
    >>> np.take_along_axis(x, ind, axis=1)  # same as np.sort(x, axis=1)
    array([[0, 3],
           [2, 2]])

    Indices of the sorted elements of a N-dimensional array:

    >>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape)
    >>> ind
    (array([0, 1, 1, 0]), array([0, 0, 1, 1]))
    >>> x[ind]  # same as np.sort(x, axis=None)
    array([0, 2, 2, 3])

    Sorting with keys:

    >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
    >>> x
    array([(1, 0), (0, 1)],
          dtype=[('x', '<i4'), ('y', '<i4')])

    >>> np.argsort(x, order=('x','y'))
    array([1, 0])

    >>> np.argsort(x, order=('y','x'))
    array([0, 1])

    """
    return _wrapfunc(a, 'argsort', axis=axis, kind=kind, order=order)

正文:

x=np.array([[0,3],[2,2]])
x
Out[23]: 
array([[0, 3],
       [2, 2]])
np.argsort(x)
Out[24]: 
array([[0, 1],
       [0, 1]], dtype=int64)
np.argsort(x,dim=-1)
Traceback (most recent call last):
  File "D:\Anaconda\envs\deep_learning\lib\site-packages\IPython\core\interactiveshell.py", line 3397, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-25-dcc1a27af835>", line 1, in <cell line: 1>
    np.argsort(x,dim=-1)
  File "<__array_function__ internals>", line 179, in argsort
TypeError: _argsort_dispatcher() got an unexpected keyword argument 'dim'
np.argsort(x,axis=-1)
Out[26]: 
array([[0, 1],
       [0, 1]], dtype=int64)
x
Out[27]: 
array([[0, 3],
       [2, 2]])
np.argsort(x,axis=0)
Out[28]: 
array([[0, 1],
       [1, 0]], dtype=int64)
np.argsort(x,axis=0)
Out[29]: 
array([[0, 1],
       [1, 0]], dtype=int64)
x(np.argsort(x,axis=0))
Traceback (most recent call last):
  File "D:\Anaconda\envs\deep_learning\lib\site-packages\IPython\core\interactiveshell.py", line 3397, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-30-6b7c4db453e7>", line 1, in <cell line: 1>
    x(np.argsort(x,axis=0))
TypeError: 'numpy.ndarray' object is not callable
np.take_along_axis(x,np.argsort(x,axis=0))
Traceback (most recent call last):
  File "D:\Anaconda\envs\deep_learning\lib\site-packages\IPython\core\interactiveshell.py", line 3397, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-31-8860fc0ed398>", line 1, in <cell line: 1>
    np.take_along_axis(x,np.argsort(x,axis=0))
  File "<__array_function__ internals>", line 179, in take_along_axis
TypeError: _take_along_axis_dispatcher() missing 1 required positional argument: 'axis'
np.take_along_axis(x,np.argsort(x,axis=0),axis=0)
Out[32]: 
array([[0, 2],
       [2, 3]])
x
Out[33]: 
array([[0, 3],
       [2, 2]])
np.take_along_axis(x,np.argsort(x,axis=0),axis=1)
Out[34]: 
array([[0, 3],
       [2, 2]])
x
Out[35]: 
array([[0, 3],
       [2, 2]])
np.argsort(x,axis=0)
Out[36]: 
array([[0, 1],
       [1, 0]], dtype=int64)
xx=np.array([[0,3],[0,3]])
xx.shape
Out[38]: (2, 2)
np.take_along_axis(xx,np.argsort(x,axis=0),axis=1)
Out[39]: 
array([[0, 3],
       [3, 0]])
np.take_along_axis(x,np.argsort(x,axis=0),axis=1)
Out[40]: 
array([[0, 3],
       [2, 2]])
np.take_along_axis(x,np.argsort(x,axis=0),axis=0)
Out[41]: 
array([[0, 2],
       [2, 3]])
np.take_along_axis(x,np.argsort(x,axis=0)[::-1],axis=0)
Out[42]: 
array([[2, 3],
       [0, 2]])
x
Out[43]: 
array([[0, 3],
       [2, 2]])
np.argsort(x,axis=0)[::-1]
Out[44]: 
array([[1, 0],
       [0, 1]], dtype=int64)
np.take_along_axis(x,np.argsort(x,axis=0)[::-1],axis=-1)
Out[45]: 
array([[3, 0],
       [2, 2]])

xx=np.array([[1,2,3],[7,8,9],[4,5,6]])
xx
Out[50]: 
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])
np.argsort(xx)
Out[51]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
np.argsort(xx,axis=-1)
Out[52]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
np.argsort(xx,axis=0)
Out[53]: 
array([[0, 0, 0],
       [2, 2, 2],
       [1, 1, 1]], dtype=int64)
xx
Out[54]: 
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])
np.argsort(xx,axis=0)[::-1]
Out[55]: 
array([[1, 1, 1],
       [2, 2, 2],
       [0, 0, 0]], dtype=int64)
xx_ind=np.argsort(xx,axis=0)[::-1]
xx_ind
Out[57]: 
array([[1, 1, 1],
       [2, 2, 2],
       [0, 0, 0]], dtype=int64)
np.take_along_axis(xx,xx_ind,axis=0)
Out[58]: 
array([[7, 8, 9],
       [4, 5, 6],
       [1, 2, 3]])
np.take_along_axis(xx,xx_ind,axis=-1)
Out[59]: 
array([[2, 2, 2],
       [9, 9, 9],
       [4, 4, 4]])

失效的情况:

xx
Out[78]: 
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])
np.argsort(xx,axis=1)
Out[79]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
np.argsort(xx,axis=1)[::-1]
Out[80]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
xx.argsort(axis=-1)
Out[81]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
xx.argsort(axis=-1)[::-1]
Out[82]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)

解决办法:

反转第二维

xx.argsort(axis=-1)[::,::-1]
Out[84]: 
array([[2, 1, 0],
       [2, 1, 0],
       [2, 1, 0]], dtype=int64)
xx
Out[85]: 
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])
xx.argsort(axis=-1)
Out[86]: 
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]], dtype=int64)
np.take_along_axis(xx,xx.argsort(axis=-1)[::,::-1],axis=-1)
Out[87]: 
array([[3, 2, 1],
       [9, 8, 7],
       [6, 5, 4]])

附:

将二维列表当成一维列表,反转所有元素:

yy=np.array([[5,3,7],[1,9,8],[6,2,4]])
np.argsort(yy,axis=0)
Out[121]: 
array([[1, 2, 2],
       [0, 0, 0],
       [2, 1, 1]], dtype=int64)
yy
Out[122]: 
array([[5, 3, 7],
       [1, 9, 8],
       [6, 2, 4]])
np.argsort(yy,axis=0)[::-1]
Out[123]: 
array([[2, 1, 1],
       [0, 0, 0],
       [1, 2, 2]], dtype=int64)
np.argsort(yy,axis=0)
Out[124]: 
array([[1, 2, 2],
       [0, 0, 0],
       [2, 1, 1]], dtype=int64)

三维列表失效:

yy=np.array([[[5,3,7],[1,9,8],[6,2,4]]])
np.argsort(yy,axis=0)
Out[126]: 
array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]], dtype=int64)
np.argsort(yy[0],axis=0)
Out[127]: 
array([[1, 2, 2],
       [0, 0, 0],
       [2, 1, 1]], dtype=int64)
np.argsort(yy[0],axis=0)[::-1]
Out[128]: 
array([[2, 1, 1],
       [0, 0, 0],
       [1, 2, 2]], dtype=int64)

猜你喜欢

转载自blog.csdn.net/nyist_yangguang/article/details/124674532