按列排序NumPy数组

512 投票
16 回答
531201 浏览
提问于 2025-04-15 22:40

我该如何按照NumPy数组的第n列进行排序呢?

举个例子,假设有这样一个数组:

a = array([[9, 2, 3],
           [4, 5, 6],
           [7, 0, 5]])

我想要根据a的第二列来排序这些行,得到:

array([[7, 0, 5],
       [9, 2, 3],
       [4, 5, 6]])

16 个回答

59

你可以按照Steve Tjoa的方法,对多个列进行排序。方法是使用一种稳定的排序算法,比如归并排序,然后从最不重要的列开始,逐步到最重要的列来排序:

a = a[a[:,2].argsort()] # First sort doesn't need to be stable.
a = a[a[:,1].argsort(kind='mergesort')]
a = a[a[:,0].argsort(kind='mergesort')]

这样排序的顺序是先按第0列,然后是第1列,再到第2列。

182

@steve回答其实是最优雅的做法。

想要了解“正确”的方法,可以查看numpy.ndarray.sort中的order参数。

不过,你需要把你的数组看作是一个带字段的数组(结构化数组)。

如果你一开始没有定义带字段的数组,那么“正确”的方法会显得相当麻烦……

举个简单的例子,想要对数组进行排序并返回一个副本:

In [1]: import numpy as np

In [2]: a = np.array([[1,2,3],[4,5,6],[0,0,1]])

In [3]: np.sort(a.view('i8,i8,i8'), order=['f1'], axis=0).view(np.int)
Out[3]: 
array([[0, 0, 1],
       [1, 2, 3],
       [4, 5, 6]])

如果想要在原地排序:

In [6]: a.view('i8,i8,i8').sort(order=['f1'], axis=0) #<-- returns None

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

据我所知,@Steve的方法确实是最优雅的做法……

这种方法的唯一优点是“order”参数是一个字段列表,用来指定排序的顺序。例如,你可以先按第二列排序,再按第三列,最后按第一列,只需提供order=['f1','f2','f0']。

撰写回答