【问题标题】:Sort a numpy array by another array, along a particular axis沿特定轴按另一个数组对 numpy 数组进行排序
【发布时间】:2011-09-03 13:56:58
【问题描述】:

类似于this answer,我有一对 3D numpy 数组,ab,我想按 a 的值对 b 的条目进行排序。与this answer 不同,我只想沿数组的一个轴排序。

我对@9​​87654327@ 文档的幼稚阅读:

Returns
-------
index_array : ndarray, int
    Array of indices that sort `a` along the specified axis.
    In other words, ``a[index_array]`` yields a sorted `a`.

让我相信我可以使用以下代码进行排序:

import numpy

a = numpy.zeros((3, 3, 3))
a += numpy.array((1, 3, 2)).reshape((3, 1, 1))
print "a"
print a
"""
[[[ 1.  1.  1.]
  [ 1.  1.  1.]
  [ 1.  1.  1.]]

 [[ 3.  3.  3.]
  [ 3.  3.  3.]
  [ 3.  3.  3.]]

 [[ 2.  2.  2.]
  [ 2.  2.  2.]
  [ 2.  2.  2.]]]
"""
b = numpy.arange(3*3*3).reshape((3, 3, 3))
print "b"
print b
"""
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]]
"""
print "a, sorted"
print numpy.sort(a, axis=0)
"""
[[[ 1.  1.  1.]
  [ 1.  1.  1.]
  [ 1.  1.  1.]]

 [[ 2.  2.  2.]
  [ 2.  2.  2.]
  [ 2.  2.  2.]]

 [[ 3.  3.  3.]
  [ 3.  3.  3.]
  [ 3.  3.  3.]]]
"""

##This isnt' working how I'd like
sort_indices = numpy.argsort(a, axis=0)
c = b[sort_indices]
"""
Desired output:

[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]]
"""
print "Desired shape of b[sort_indices]: (3, 3, 3)."
print "Actual shape of b[sort_indices]:"
print c.shape
"""
(3, 3, 3, 3, 3)
"""

这样做的正确方法是什么?

【问题讨论】:

    标签: python sorting multidimensional-array numpy


    【解决方案1】:

    您仍然需要为其他两个维度提供索引才能正常工作。

    >>> a = numpy.zeros((3, 3, 3))
    >>> a += numpy.array((1, 3, 2)).reshape((3, 1, 1))
    >>> b = numpy.arange(3*3*3).reshape((3, 3, 3))
    >>> sort_indices = numpy.argsort(a, axis=0)
    >>> static_indices = numpy.indices((3, 3, 3))
    >>> b[sort_indices, static_indices[1], static_indices[2]]
    array([[[ 0,  1,  2],
            [ 3,  4,  5],
            [ 6,  7,  8]],
    
           [[18, 19, 20],
            [21, 22, 23],
            [24, 25, 26]],
    
           [[ 9, 10, 11],
            [12, 13, 14],
            [15, 16, 17]]])
    

    numpy.indices 在通过其他两个轴(或 n - 1 个轴,其中 n = 轴总数)“展平”时计算数组每个轴的索引。换句话说,这个(为长篇道歉):

    >>> static_indices
    array([[[[0, 0, 0],
             [0, 0, 0],
             [0, 0, 0]],
    
            [[1, 1, 1],
             [1, 1, 1],
             [1, 1, 1]],
    
            [[2, 2, 2],
             [2, 2, 2],
             [2, 2, 2]]],
    
    
           [[[0, 0, 0],
             [1, 1, 1],
             [2, 2, 2]],
    
            [[0, 0, 0],
             [1, 1, 1],
             [2, 2, 2]],
    
            [[0, 0, 0],
             [1, 1, 1],
             [2, 2, 2]]],
    
    
           [[[0, 1, 2],
             [0, 1, 2],
             [0, 1, 2]],
    
            [[0, 1, 2],
             [0, 1, 2],
             [0, 1, 2]],
    
            [[0, 1, 2],
             [0, 1, 2],
             [0, 1, 2]]]])
    

    这些是每个轴的标识索引;当用于索引 b 时,它们重新创建 b。

    >>> b[static_indices[0], static_indices[1], static_indices[2]]
    array([[[ 0,  1,  2],
            [ 3,  4,  5],
            [ 6,  7,  8]],
    
           [[ 9, 10, 11],
            [12, 13, 14],
            [15, 16, 17]],
    
           [[18, 19, 20],
            [21, 22, 23],
            [24, 25, 26]]])
    

    作为 numpy.indices 的替代品,您可以使用 numpy.ogrid,正如 unutbu 建议的那样。由于ogrid 生成的对象更小,我将创建所有三个轴,只是为了保持一致性,但请注意 unutbu 的注释,以便通过仅生成两个来执行此操作。

    >>> static_indices = numpy.ogrid[0:a.shape[0], 0:a.shape[1], 0:a.shape[2]]
    >>> a[sort_indices, static_indices[1], static_indices[2]]
    array([[[ 1.,  1.,  1.],
            [ 1.,  1.,  1.],
            [ 1.,  1.,  1.]],
    
           [[ 2.,  2.,  2.],
            [ 2.,  2.,  2.],
            [ 2.,  2.,  2.]],
    
           [[ 3.,  3.,  3.],
            [ 3.,  3.,  3.],
            [ 3.,  3.,  3.]]])
    

    【讨论】:

    • 我喜欢这个答案。为了节省一些内存,也许将static_indices 更改为static_indices = np.ogrid[0:a.shape[1],0:a.shape[2]]。这将产生更小的数组,但会通过利用广播来做与np.indices 相同的事情。可以这样使用:b[sort_indices, static_indices[1], static_indices[2]].
    • 错了,b[sort_indices, static_indices[0], static_indices[1]]
    • @unutbu,谢谢!我还在了解 numpy 非常丰富的索引系统;很高兴了解一种自动生成可广播索引的方法。
    猜你喜欢
    • 2011-09-03
    • 1970-01-01
    • 2020-01-15
    • 2011-02-11
    • 2013-10-04
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多