我如何排序一个NumPy数组的第n列?

例如,给定:

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

我想对a的行按第二列进行排序,得到:

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

当前回答

#用于按列1排序

indexofsort=np.argsort(dataset[:,0],axis=-1,kind='stable') 
dataset   = dataset[indexofsort,:]

其他回答

按a的第二列排序:

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

一个稍微复杂一点的lexsort示例-在第一列降序,在第二列次级升序。lexsort的技巧是按行排序(因此使用. t),并优先考虑最后一行。

In [120]: b=np.array([[1,2,1],[3,1,2],[1,1,3],[2,3,4],[3,2,5],[2,1,6]])
In [121]: b
Out[121]: 
array([[1, 2, 1],
       [3, 1, 2],
       [1, 1, 3],
       [2, 3, 4],
       [3, 2, 5],
       [2, 1, 6]])
In [122]: b[np.lexsort(([1,-1]*b[:,[1,0]]).T)]
Out[122]: 
array([[3, 1, 2],
       [3, 2, 5],
       [2, 1, 6],
       [2, 3, 4],
       [1, 1, 3],
       [1, 2, 1]])

如果有人想在程序的关键部分使用排序,这里是不同方案的性能比较:

import numpy as np
table = np.random.rand(5000, 10)

%timeit table.view('f8,f8,f8,f8,f8,f8,f8,f8,f8,f8').sort(order=['f9'], axis=0)
1000 loops, best of 3: 1.88 ms per loop

%timeit table[table[:,9].argsort()]
10000 loops, best of 3: 180 µs per loop

import pandas as pd
df = pd.DataFrame(table)
%timeit df.sort_values(9, ascending=True)
1000 loops, best of 3: 400 µs per loop

所以,看起来使用argsort进行索引是目前为止最快的方法…

感谢这篇文章:https://stackoverflow.com/a/5204280/13890678

我用结构化数组找到了一个更“通用”的答案。 我认为这种方法的一个优点是代码更容易阅读。

import numpy as np
a = np.array([[9, 2, 3],
           [4, 5, 6],
           [7, 0, 5]])

struct_a = np.core.records.fromarrays(
    a.transpose(), names="col1, col2, col3", formats="i8, i8, i8"
)
struct_a.sort(order="col2")

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

@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]])

据我所知,史蒂夫的方法真的是最优雅的……

该方法的唯一优点是“order”参数是一个字段列表,用于排序搜索。例如,您可以通过order=['f1','f2','f0']按第二列排序,然后是第三列,然后是第一列。