简体   繁体   English

根据各个行对 3D 数组中的 2D 数组列进行单独排序

[英]Individually sort columns of 2D arrays within a 3D array based on their individual rows

I know that we can sort the columns of an 2D numpy array based on a row the following way:我知道我们可以通过以下方式基于行对 2D numpy 数组的列进行排序:

a = np.array([[1,4,7],
              [3,1,5],
              [9,5,8]])

a = a[:, a[1, :].argsort()]

Out: [[4,1,7],
      [1,3,5],
      [5,9,8]]

Please note that this is indeed what I want.请注意,这确实是我想要的。 The second row (index=1) is now sorted and the values in rows 0 and 2 also shifted accordingly.第二行(索引 = 1)现在已排序,第 0 行和第 2 行中的值也相应地移动。 That is, the column positions change based on the sorting order of row 1.也就是说,列位置会根据第 1 行的排序顺序发生变化。

But now to my problem: I don't have a 2D array but a 3D array (ie an array of 2D arrays).但是现在我的问题是:我没有 2D 数组,而是 3D 数组(即 2D 数组的数组)。

a = np.array([[[1,4,7],
               [3,1,5],
               [9,5,8]],
              [[2,8,7],
               [3,8,1],
               [9,2,8]]])

I still want to sort the columns of the 2D arrays, individually, based on the values of their respective rows 1. The desired result would be:我仍然想根据各自第 1 行的值对 2D 数组的列进行单独排序。所需的结果是:

([[[4,1,7],
   [1,3,5],
   [5,9,8]],
  [[7,2,8],
   [1,3,8],
   [8,9,2]]])

I tried the following but the results are not as desired:我尝试了以下但结果并不如预期:

a = a[:, :, a[: , 1, :].argsort()]

Try np.take_along_axis :试试np.take_along_axis

np.take_along_axis(a,a[:,1].argsort()[:,None], axis=2)

Out:出去:

array([[[4, 1, 7],
        [1, 3, 5],
        [5, 9, 8]],

       [[7, 2, 8],
        [1, 3, 8],
        [8, 9, 2]]])

Honestly, don't ask me why it works :-)老实说,不要问我为什么它有效:-)

You can use a combination of numpy.argsort and numpy.take_along_axis :您可以使用numpy.argsortnumpy.take_along_axis的组合:

idx = np.argsort(a, axis=2)
np.take_along_axis(a, idx[:,None,1], axis=2)

It works by getting the sorting order from argsort and then keeping only the relevant row (1 here), reshapes to broadcast the operation of take_along_axis on all the other rows.它的工作原理是从argsort获取排序顺序,然后只保留相关行(此处为 1),重新take_along_axis在所有其他行上广播take_along_axis的操作。

output:输出:

array([[[4, 1, 7],
        [1, 3, 5],
        [5, 9, 8]],

       [[7, 2, 8],
        [1, 3, 8],
        [8, 9, 2]]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM