Numpy 在多列上排序 ndarray

新手上路,请多包涵

我得到一个 ndarray 从文件中读取它,就像这样

my_data = np.genfromtxt(input_file, delimiter='\t', skip_header=0)

示例输入(已解析)

 [[   2.    1.    2.    0.]
 [   2.    2.  100.    0.]
 [   2.    3.  100.    0.]
 [   3.    1.    2.    0.]
 [   3.    2.    4.    0.]
 [   3.    3.    6.    0.]
 [   4.    1.    2.    0.]
 [   4.    2.    4.    0.]
 [   4.    3.    6.    0.]]

更长的 示例输入(未解析)。

前两列应该是 int ,而最后两列应该是 float ,但这就是我得到的。欢迎提出建议。

主要问题是,我正在尝试使用 Numpy 对其进行排序,以便对行进行排序,优先考虑第二列中的数字,然后是第一列中的数字。

所需输出示例

[[   2.    1.    2.    0.]
 [   3.    1.    2.    0.]
 [   4.    1.    2.    0.]
 [   2.    2.  100.    0.]
 [   3.    2.    4.    0.]
 [   4.    2.    4.    0.]
 [   2.    3.  100.    0.]
 [   3.    3.    6.    0.]
 [   4.    3.    6.    0.]]

我知道 这个答案,它适用于对单个列上的行进行排序。

我尝试对第二列进行排序,因为第一列已经排序,但这还不够。有时,第一列也会被重新排序,很糟糕。

 new_data = my_data[my_data[:, 1].argsort()]
print(new_data)

#output
[[   2.    1.    2.    0.]
 [   4.    1.    2.    0.] #ouch
 [   3.    1.    2.    0.] #ouch
 [   2.    2.  100.    0.]
 [   3.    2.    4.    0.]
 [   4.    2.    4.    0.]
 [   2.    3.  100.    0.]
 [   3.    3.    6.    0.]
 [   4.    3.    6.    0.]]

我也查过 这个问题

答案提到

这里的问题是 np.lexsort 或 np.sort 不适用于 dtype 对象的数组。要解决该问题,您可以在创建 order_list 之前对 rows_list 进行排序:

 import operator
rows_list.sort(key=operator.itemgetter(0,1,2))

但是我在 sort 类型的函数中没有 key 参数 ndarray 。就我而言,合并字段不是替代方案。

此外,我没有标头,因此,如果我尝试使用 order 参数进行排序,则会出现错误。

 ValueError: Cannot specify order when the array has no fields.

我宁愿就地排序或至少获得相同类型的结果 ndarray 。然后我想把它保存到一个文件中。

在不弄乱数据类型的情况下,我该怎么做?

原文由 Agostino 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

Import 让 Numpy 猜测类型并就地排序:

 import numpy as np

# let numpy guess the type with dtype=None
my_data = np.genfromtxt(infile, dtype=None, names=["a", "b", "c", "d"])

# access columns by name
print(my_data["b"]) # column 1

# sort column 1 and column 0
my_data.sort(order=["b", "a"])

# save specifying required format (tab separated values)
np.savetxt("sorted.tsv", my_data, fmt="%d\t%d\t%.6f\t%.6f"

或者,指定输入格式并排序到新数组:

 import numpy as np

# tell numpy the first 2 columns are int and the last 2 are floats
my_data = np.genfromtxt(infile, dtype=[('a', '<i8'), ('b', '<i8'), ('x', '<f8'), ('d', '<f8')])

# access columns by name
print(my_data["b"]) # column 1

# get the indices to sort the array using lexsort
# the last element of the tuple (column 1) is used as the primary key
ind = np.lexsort((my_data["a"], my_data["b"]))

# create a new, sorted array
sorted_data = my_data[ind]

# save specifying required format (tab separated values)
np.savetxt("sorted.tsv", sorted_data, fmt="%d\t%d\t%.6f\t%.6f")

输出:

 2   1   2.000000    0.000000
3   1   2.000000    0.000000
4   1   2.000000    0.000000
2   2   100.000000  0.000000
3   2   4.000000    0.000000
4   2   4.000000    0.000000
2   3   100.000000  0.000000
3   3   6.000000    0.000000
4   3   6.000000    0.000000

原文由 Padraic Cunningham 发布,翻译遵循 CC BY-SA 3.0 许可协议

numpy ndarray 按第一、第二或第三列排序:

 >>> a = np.array([[1,30,200], [2,20,300], [3,10,100]])

>>> a
array([[  1,  30, 200],
       [  2,  20, 300],
       [  3,  10, 100]])

>>> a[a[:,2].argsort()]           #sort by the 3rd column ascending
array([[  3,  10, 100],
       [  1,  30, 200],
       [  2,  20, 300]])

>>> a[a[:,2].argsort()][::-1]     #sort by the 3rd column descending
array([[  2,  20, 300],
       [  1,  30, 200],
       [  3,  10, 100]])

>>> a[a[:,1].argsort()]        #sort by the 2nd column ascending
array([[  3,  10, 100],
       [  2,  20, 300],
       [  1,  30, 200]])

解释这里发生了什么: argsort() 传回一个包含其父级整数序列的数组: https ://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html

 >>> x = np.array([15, 30, 4, 80, 6])
>>> np.argsort(x)
array([2, 4, 0, 1, 3])

按第 3 列排序,然后按第 2 列排序,然后按第 1 列排序:

 >>> a = np.array([[2,30,200], [1,30,200], [1,10,200]])

>>> a
array([[  2,  30, 200],
       [  1,  30, 200],
       [  1,  10, 200]])

>>> a[np.lexsort((a[:,2], a[:,1],a[:,0]))]
array([[  1,  10, 200],
       [  1,  30, 200],
       [  2,  30, 200]])

与上面相同但相反:

 >>> a[np.lexsort((a[:,2], a[:,1],a[:,0]))][::-1]
array([[  2  30 200]
       [  1  30 200]
       [  1  10 200]])

原文由 Eric Leschinski 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题