2012-01-01 2 views
2

나는 word : value (float) 쌍의 큰 (수천 개) 컬렉션을 가지고 있습니다. 나는 가치의 최고를 찾아 내고 관련 단어를 추출 할 필요가있다. 예를 들어 (a, 2.4), (b, 5.2), (c, 1.2), (d, 9.2), (e, 6.3), (f, 0.4) 나는 출력으로 (d, 9.2)를 원한다.사전에서 numpy 배열 대 최대 값을 찾는 성능

현재 이러한 튜플을 저장하고 max 연산자를 사용하여 사전의 최대 키 값을 검색하는 사전을 사용하고 있습니다. 나는 질적 인 배열이 더 효율적 일지 궁금해하고 있었다. 여기에 전문가의 의견을 구하는 것.

+0

튜플을 하나의 구조에 저장해야합니까? 아니면 파리에서 생성 할 수 있습니까? 최대 항목이 여러 개 필요한 경우 'heapq'http://docs.python.org/library/heapq.html을 사용할 수 있습니다. 어떤 종류의 문제를 해결하고 있으며이 부분이 문제의 근원이라고 확신합니까? –

+0

구조체에 튜플을 저장해야합니다. 난 그냥 최대 숫자 값과 해당 '키'를 찾고 싶다. – Dexter

답변

2

여기 Numpy를 사용하면 부동 값을 별도의 ndarray에 보관해야합니다. argmax을 사용하여 최대 값의 색인을 찾아 별도의 목록에서 단어를 가져옵니다. 이것은 매우 빠르지 만 max를 찾기 위해 ndarray를 생성하는 것은 쉽지 않습니다. 예 :

import numpy as np 
import operator 

names = [str(x) for x in xrange(10000)] 
values = [float(x) for x in xrange(10000)] 
tuples = zip(names, values) 
dic = dict(tuples) 
npvalues = np.fromiter(values, np.float) 

def fa(): 
    return names[npvalues.argmax()] 

def fb(): 
    return max(tuples, key=operator.itemgetter(1))[0] 

def fc(): 
    return max(dic, key=dic.get) 

def fd(): 
    v = np.fromiter((x[1] for x in tuples), np.float) 
    return tuples[v.argmax()][0] 

타이밍 : FA 67 μS, FB 2300 μS, FC 2580 μS는 3780 μS을 전략 중.

따라서 Numpy 배열을 구성하는 시간이 고려되지 않은 경우 Numpy (fa)를 사용하면 일반 목록 (fb) 또는 사전 (fc)을 사용하는 것보다 30 배 이상 빠릅니다. (fd가 고려)

+0

* "질적 인 배열이 더 효율적인지 궁금 해서요"* ... 그리고 대답은 ...? – mac

+0

@mac 답변에 결론을 추가했습니다. –

+0

질문에 대답하기 위해 OP에서 더 많은 정보가 필요합니다. 그는 현재 dict 저장소를이 단어 값 쌍으로 사용하고 있으며 대신 ndarray에 저장하려고합니까? –

4

이 경우 numpy 배열이 어떻게 도움이되는지 나는 알지 못합니다.

특히 데이터 구조를 다른 것으로 변환하면 (numpy 배열 또는 heapq의 튜플 목록) 각 튜플에 대해 반복되는 최대 값을 찾는 것보다 훨씬 느립니다. 데이터 구조를 변환 할 때 원본 구조를 반복하고 새 구조체에 대해 객체를 인스턴스화하고 새 구조체에 값을 저장하는 동시에 새 구조체를 사용하여 요청 된 값을 가져와야하기 때문입니다.

목록의 내장 함수 나 메서드를 사용하면 계산 속도가 빨라집니다. 내가 생각할 수있는 가장 사소한 구현 : 당신은 또한 가장 낮은 값 등의 물건 또는 정렬을 통해 목록 당신이 통과 할 수있는 값을 보여주고에 관심이 있다면

>>> li = [('a', 10), ('b', 30), ('c', 20)] 
>>> max(li, key=lambda e : e[1])[0] 
'b' 

다른 가능한 것들 (그래서 당신은 원래 목록을 검사 한 번만) :!

>>> li = [('a', 10), ('b', 30), ('c', 20)] 
>>> li.sort(key=lambda e : e[1]) 
>>> li 
[('a', 10), ('c', 20), ('b', 30)] 
>>> li[-1][0] 
'b' 

또는 :

>>> sorted(li, key=lambda e: e[1])[-1][0] 
'b' 

HTH!

+0

Mac, 답장을 보내 주셔서 감사합니다. 튜플은 먼저 사전에 넣은 다음 ndarray로 변환하는 대신 ndarray에 직접 생성 될 수 있습니다. 원래 게시물의 예제는 데모 용이었습니다. – Dexter