2017-02-27 17 views
2

私は並べ替えようとしている配列を持っています。エントリの一部は文字列なので、numpyはすべてを文字列(数値を含む)として扱います。全体的にはこれはうまくいき、実際にはいくつかの場所でそれを活用していますが、ソートしようとするといくつかの問題が生じます。文字列ベースの数値をlexsort(python)で並べ替える

文字列の長さが違うと問題が発生します(ソートが50,120,110の場合、50,110,120ではなく110,120,50となります)。

以下は、何が起こっているかの簡単な例です。誰もがこの問題を克服する方法を知っていますか(文字列として要素を並べ替えることができればそれは素晴らしいでしょうが、そうでない場合に行うことができます)。

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) 

ご不明な点などございましたら、お気軽にお問い合わせください。いつものように、これが重複している場合は、助けを前もってお礼して&お詫び申し上げます。

答えて

2

変換lexsortの型をINTと、入力配列のインデックスにそれらのLEX-ソートインデックスを使用する -

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') 
関連する問題