【问题标题】:Sort N-D numpy array by column with a smaller N-D array使用较小的 NDarray 按列对 A-N numpy 数组进行排序
【发布时间】:2016-03-12 00:34:57
【问题描述】:

我知道通过Sort N-D numpy array by another 1-D array 使用花哨的索引,我可以用b 定义我想要按列排序的顺序来执行以下c = a[:, :, b]

>>> a = np.array([[[ 0,  1], [ 2,  3]],
                  [[ 4,  5], [ 6,  7]],
                  [[ 8,  9], [10, 11]]])
>>> b = np.array([1, 0])
>>> c = a[:, :, b]
>>> c
array([[[ 1,  0],
        [ 3,  2]],

       [[ 5,  4],
        [ 7,  6]],

       [[ 9,  8],
        [11, 10]]])

现在我增加b 2 个输入到b2 对应于我想如何对a 中的每组2x2 进行排序

>>> b2 = np.array([[1, 0], [0, 1], [1, 0]])
>>> c2 = ?
>>> c2
array([[[ 1,  0],
        [ 3,  2]],

       [[ 4,  5],
        [ 6,  7]],

       [[ 9,  8],
        [11, 10]]])

我有一组更大的输入,我有一个函数,它返回一个类似于“b2”的数组,它为我提供了我应该获取的信息。因此,我可以知道我应该在c2 = ? 中填写什么以获得所需的结果吗?

【问题讨论】:

  • 对于预期的输出,b2 不应该是 np.array([[1, 0], [0, 1], [1, 0]])(最后一行交换)吗?
  • @ajcr 感谢您发现这个错误! :)

标签: python arrays sorting numpy


【解决方案1】:

类似于@Divakar's 解决方案但没有transpose

In [259]: I,J, K = np.ogrid[:3,:2,:2]

In [260]: a[I, J, b[:,None,:]]
Out[260]: 
array([[[ 1,  0],
        [ 3,  2]],

       [[ 4,  5],
        [ 6,  7]],

       [[ 9,  8],
        [11, 10]]])

我使用ogrid(或np.ix_)作为生成2个3d数组的紧凑方式,这些数组使用b[:,None,:]进行广播以生成一组(3,2,2)索引。

与完整的Nones 等效的是:

a[np.arange(3)[:,None,None], np.arange(2)[None,:,None], b[:,None,:]]

(这更清楚地表明b 正在选择沿第一个和最后一个轴的项目)

要查看完整的广播索引数组,请打印:

 np.broadcast_arrays(I,J,b[:,None,:])

【讨论】:

  • 谢谢!与 Divakar 的回答类似,我学到了很多东西,也感谢您一步一步地解释它。
【解决方案2】:

这是 fancy-indexing 的一种方法 -

(a[np.arange(a.shape[0])[:,None],:,b2]).transpose(0,2,1)

示例运行 -

In [191]: a
Out[191]: 
array([[[7, 8, 5, 2, 0],
        [6, 7, 0, 7, 1],
        [7, 6, 5, 4, 0]],

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

       [[3, 2, 7, 3, 7],
        [4, 3, 0, 1, 5],
        [4, 3, 7, 8, 7]]])

In [192]: b2
Out[192]: 
array([[1, 2, 4, 3, 0],
       [4, 2, 0, 1, 3],
       [1, 3, 4, 0, 2]])

In [193]: (a[np.arange(a.shape[0])[:,None],:,b2]).transpose(0,2,1)
Out[193]: 
array([[[8, 5, 0, 2, 7],
        [7, 0, 1, 7, 6],
        [6, 5, 0, 4, 7]],

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

       [[2, 3, 7, 3, 7],
        [3, 1, 5, 4, 0],
        [3, 8, 7, 4, 7]]])

【讨论】:

【解决方案3】:

如果没有人找到一个纯粹的花式索引解决方案,这里是一个循环通过第一个轴的解决方案:

np.asarray([a[n,:,p] for n,p in enumerate(b2)])

array([[[ 1,  3],
    [ 0,  2]],

   [[ 4,  6],
    [ 5,  7]],

   [[ 9, 11],
    [ 8, 10]]])

【讨论】:

  • 感谢您的回答!我正在寻找一个花哨的索引解决方案将是更好的 bcos 速度。 :)
猜你喜欢
  • 2011-02-19
  • 2021-05-18
  • 2021-09-21
  • 2018-05-12
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多