2016-06-16 5 views
0

numpy를 요소의 길이로 사용하여 문자열 배열을 정렬하려고합니다.numpy를 사용하여 문자열 배열 정렬

>>> arr = ["year","month","eye","i","stream","key","house"] 
>>> x = np.sort(arr, axis=-1, kind='mergesort') 
>>> print(x) 
['eye' 'house' 'i' 'key' 'month' 'stream' 'year'] 

그러나 영숫자 순으로 정렬됩니다. 길이에 따라 numpy를 사용하여 정렬하려면 어떻게해야합니까?

+1

속도가 빠를 것이라고 생각하여이 작업을 수행하는 경우 numpy 작동 방식을 이해하지 못합니다. 같은 크기의 바이트를 차지하는 요소를 위해 설계되었습니다. 동일하지 않은 길이의 문자열은이를 만족시키지 않아서 numpy로 객체에 래핑되고 아마 더 비효율적입니다. –

+1

numpy를 사용하는 데에는 많은 이유가 있지만 Oliver의 발언에 동의해야합니다. 이 코드 예제는 당연히 더 아름답고/컴팩트 한 구문을 허용하는 파이썬의 내장 정렬 방법을 요구합니다. (하지만 어쩌면 당신은 numpy를 사용하는 다른 이유가있을 수 있으며 이는 단지 예일뿐입니다). – sascha

+0

고맙습니다. 현재로서는, 나는 numpy에 처음이다. 그리고 나는 단지 이해하려고 노력하고있다. @ sascha 그럼 길이가 너무 많은 문자열 요소를 정렬 할 때 사용할 수있는 방법은 무엇입니까? 파이썬 고유의 정렬 방법? – GGG

답변

3

문자열 길이가 포함 된 도우미 배열을 추가 한 다음이 길이에 따라 정렬 할 인덱스를 제공하는 numpy의 argsort를 사용하십시오. 색인이 인덱스와 원본 데이터 다음 key 기능이 가장 빠른으로

import numpy as np 
arr = np.array(["year","month","eye","i","stream","key","house"]) # np-array needed for later indexing 
arr_ = map(lambda x: len(x), arr) # remark: py3 would work different here 
x = arr[np.argsort(arr_)] 
print(x) 
+2

'numpy.char.str_len'도 있습니다 (하지만 약간 빠름). –

+0

고마워요.하지만 나에게 "[ 'year']" – GGG

+0

을주었습니다. python3을 사용하고 내 코멘트를 무시했기 때문입니다. map 대신 arr_ = list (map ...)를 사용하십시오. (... Py3의 map은리스트/배열이 아닌 반복자를 반환하므로이 여분의 단계가 필요합니다. – sascha

1

내가 arr1=arr*1000에 목록을 확장하면, 파이썬 목록 정렬 len를 사용하여.

In [77]: len(arr1) 
Out[77]: 7000 

In [78]: timeit sarr=sorted(arr1,key=len) 
100 loops, best of 3: 3.03 ms per loop 

In [79]: %%timeit 
arrA=np.array(arr1) 
larr=[len(i) for i in arrA] # list comprehension works same as map 
sarr=arrA[np.argsort(larr)] 
    ....: 
100 loops, best of 3: 7.77 ms per loop 

목록을 배열로 변환하는 데 약 1ms가 소요됩니다 (특히 작은 목록의 경우 상당한 오버 헤드가 발생 함). 이미 생성 된 배열을 사용하고 np.char.str_len 시간은 여전히 ​​파이썬 sort보다 느립니다.

In [83]: timeit sarr=arrA[np.argsort(np.char.str_len(arrA))] 
100 loops, best of 3: 6.51 ms per loop 

np.char 기능이 편리 할 수 ​​있습니다, 그들은 여전히 ​​기본적으로 해당 str 방법을 적용 목록을 반복.

일반적으로 argsortkey 기능과 동일한 기능을 제공합니다.