2012-01-01 22 views
2

私はワード:値(浮動小数点数)の大きな(1000単位で)コレクションを持っています。私は価値の最高を見つけ、対応する関連語を抽出する必要があります。例えば、私は(a、2.4)、(b、5.2)、(c、1.2)、(d、9.2)、(e、6.3)、(f、0.4)を持っています。私は出力として(d、9.2)を望みます。辞書の最大値を検索するパフォーマンス対numpy配列

現在、これらのタプルを格納する辞書を使用しており、max演算子を使用して辞書の最大キー値を取得しています。私は、数が少ない配列がより効率的かどうか疑問に思っていました。ここで専門家の意見を求める。

+0

タプルは1つの構造体に格納する必要がありますか?最大アイテムが複数必要な場合は、「heapq」http://docs.python.org/library/heapq.htmlを使用できます。どのような問題を解決しているのですか?この部分が問題の原因であると確信していますか? –

+0

タプルを構造体に格納する必要があります。私はちょうど最大の数値と対応する 'キー'を見つけたいと思っています。 – Dexter

答えて

2

ここでNumpyを使用するには、float値を別の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マイクロ秒、3780マイクロ秒をfdが。

Numpy(fa)を使用すると、Numpy配列を構築する時間が考慮されていないときに、プレーンリスト(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

関連する問題