【问题标题】:Sort each column of an numpy.ndarray using the output of numpy.argsort使用 numpy.argsort 的输出对 numpy.ndarray 的每一列进行排序
【发布时间】:2017-08-30 07:47:17
【问题描述】:

我想根据之前处理的参考数组对 numpy 二维数组进行排序。 我的想法是存储我的参考数组的numpy.argsort 输出并使用它对其他数组进行排序:

In [13]: # my reference array
    ...: ref_arr = np.random.randint(10, 30, 12).reshape(3, 4)
Out[14]:
array([[12, 22, 12, 13],
       [28, 26, 21, 23],
       [24, 14, 16, 25]])

# desired output:
array([[12, 14, 12, 13],
       [24, 22, 16, 23],
       [28, 26, 21, 25]])

我尝试了什么:

In [15]: # store the sorting matrix
    ...: sm = np.argsort(ref_arr, axis=0)
Out[16]:
array([[0, 2, 0, 0],
       [2, 0, 2, 1],
       [1, 1, 1, 2]])

但不幸的是,最后一步仅适用于一维数组:

In [17]: ref_arr[sm]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-17-48b785178465> in <module>()
----> 1 ref_arr[sm]

IndexError: index 3 is out of bounds for axis 0 with size 3

我发现这个Github issue 是针对这个问题创建的,但不幸的是,它通过提到我尝试的仅适用于一维数组来解决。 ????

In a comment to this issue 提到了一个与我的问题类似的示例。 sn-p 没有解决我的问题,因为它按 row 而不是 column 对数组进行排序。但它暗示了我必须朝哪个方向移动……

a[np.arange(np.shape(a)[0])[:,np.newaxis], np.argsort(a)]

不幸的是,我对示例的理解不足以使其适应我的用例。也许有人可以在这里解释这种高级索引是如何工作的?这可能使我能够自己解决问题,但我也不介意交钥匙解决方案。 ;)

谢谢。

以防万一:我在 OS X 上使用 Python 3.6.1 和 numpy 1.12.1。

【问题讨论】:

  • 那么,a[np.arange(np.shape(a)[0])[:,np.newaxis], np.argsort(a)] 适合你,但你需要解释它是如何工作的吗?
  • 您的argsort 呼叫没有按照您说的轴排序。
  • @wedi:不,我的意思是当你说你想要另一个方向时,你的 argsort 正在沿行排序。
  • stackoverflow.com/a/33141247/901925 试图说明和解释a[np.arange(np.shape...np.argsort(a)]
  • 有一个numpy issue 让这种事情变得更容易

标签: python arrays sorting numpy


【解决方案1】:

基本上需要两个步骤:

1] 使用 axis=0 获取每个列的 argsort 索引 -

sidx = ref_arr.argsort(axis=0)

2] 使用advanced-indexing 使用sidx 选择行,即索引到第一个维度并使用另一个范围数组索引到第二个维度,这样它就可以覆盖所有列中的sidx 索引 -

out = ref_arr[sidx, np.arange(sidx.shape[1])]

示例运行 -

In [185]: ref_arr
Out[185]: 
array([[12, 22, 12, 13],
       [28, 26, 21, 23],
       [24, 14, 16, 25]])

In [186]: sidx = ref_arr.argsort(axis=0)

In [187]: sidx
Out[187]: 
array([[0, 2, 0, 0],
       [2, 0, 2, 1],
       [1, 1, 1, 2]])

In [188]: ref_arr[sidx, np.arange(sidx.shape[1])]
Out[188]: 
array([[12, 14, 12, 13],
       [24, 22, 16, 23],
       [28, 26, 21, 25]])

【讨论】:

  • 谢谢!我得到了我的解决方案,看着它我也理解了另一个例子。 :)
【解决方案2】:

截至 2018 年 5 月,它可以使用 np.take_along_axis 完成

np.take_along_axis(ref_arr, sm, axis=0)
Out[25]: 
array([[10, 16, 15, 10],
       [13, 23, 24, 12],
       [28, 26, 28, 28]])

【讨论】:

    猜你喜欢
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    相关资源
    最近更新 更多