使用lexsort(python)对基于字符串的数字进行排序

时间:2017-02-27 15:19:32

标签: python python-3.x sorting numpy

我有一个我正在尝试排序的数组。一些条目是字符串,因此numpy将所有内容视为字符串(包括数字)。总的来说这很好,我实际上在一些地方利用它,但是当尝试排序时会导致一些问题。

基本上问题来自于字符串长度不同(所以如果它的排序说50,120,110它会给出110,120,50而不是50,110,120)。

下面是一个简单的例子,说明正在发生的事情;有没有人知道如何克服这个问题(如果我可以保留元素作为排序后的字符串,那将是很好的,但如果没有,我可以做。)

import numpy as np


spam = np.array( [ [ 'Graham', 550, 29 ], [ 'John', 90, 1 ], [ 'Terry G', 450, 20 ], \
                   [ 'Eric', 550, 30   ], [ 'Terry J', 450, 20 ], [ 'Michael', 520, 33 ] ] )

print( "Original:\n")
print( spam )
print( "\n\nSorted:\n" )


spam = spam[ np.lexsort( ( spam[ :, 2 ], spam[ :, 1 ] ) ) ][ : : -1 ]

print( spam )

如果缺少任何信息等,请不要犹豫。一如既往,提前感谢帮助&如果这是重复的话道歉(就我所见,搜索没有返回相关结果)。

1 个答案:

答案 0 :(得分:2)

转换为lexsort的int类型,然后使用那些lex-sorted索引索引到输入数组 -

sidx = np.lexsort(( spam[ :, 2 ].astype(int), spam[ :, 1 ].astype(int)))
    # Or simply np.lexsort(spam[ :, 2:0:-1].astype(int).T)
spam_out = spam[sidx[::-1]]

示例运行 -

In [450]: spam
Out[450]: 
array([['Graham', '550', '29'],
       ['John', '90', '1'],
       ['Terry G', '450', '20'],
       ['Eric', '550', '30'],
       ['Terry J', '450', '20'],
       ['Michael', '520', '33']], 
      dtype='|S7')

In [451]: sidx = np.lexsort(( spam[ :, 2 ].astype(int), spam[ :, 1 ].astype(int)))

In [452]: spam[sidx[::-1]]
Out[452]: 
array([['Eric', '550', '30'],
       ['Graham', '550', '29'],
       ['Michael', '520', '33'],
       ['Terry J', '450', '20'],
       ['Terry G', '450', '20'],
       ['John', '90', '1']], 
      dtype='|S7')