1

私はPythonにまったく慣れていないため、その力を完全には認識していません。より速く動作すると思われる次のコードがあります。numpy/map を使用して実行できると思いますが、それを構築する方法がわかりません。

ここで問題となっている両方の辞書には、次のような 7 つの要素のリストによって形成される値を持つ 10,000 個のキーがあります。

T_com ={0: [[1.2, 3,.65,.63, 3, 3 , 5.5]] 1:[[1.7, 2,.55,.13, 2, 8 , 5.5]] ...10,000th key:[[3.2, 9,.15,.23, 1, 3 , 2.5]]}

このため、私の現在のコード (以下で説明) は何時間にもわたって伸びていますが、これは良くないと感じています。基本的に、両方の辞書の各キーに関連付けられたリストを読み取り、それらのスコアを計算してから、スコアを辞書に追加し、最後に ZODB に書き込みます。以下はスニペットです (ディクショナリは、上で定義R_comしたものと構造がまったく同じです)。T_com

 for tar_node,tar_community in T_com.iteritems():   # iterate over the key value pair of first dic
     for i,(ref_node,ref_community) in enumerate(R_com.iteritems()):  # iterate over second dictionary. Enumeration was required for some other operation
         score = compute_score(T_com[tar_node],R_com[ref_node])      # calculate some score   
         bTree_container.setdefault(tar_node,PersistentList () ).append( [ref_node,score,priority.pop(),0])    #Builds a list of lists associated with every value of tar_node
         if i % 2500 ==0:            # After every 2,500 values temporarily save the data to disk
             transaction.savepoint(True)
 transaction.commit()  # finally write all the data to disk 

実行時間を短縮する/ループを回避する方法について何か提案はありますか? 一般的に、そのようなケースを処理するためのPythonのベストプラクティスは何ですか?

示唆されているように、cProfile からのいくつかの結果:-

200000000 3792.449    0.000 3792.449    0.000 {numpy.core.multiarray.array}
100000000   51.033    0.000   51.186    0.000 {method 'setdefault' of 'BTrees.IOBTree.IOBTree' objects}
4

3 に答える 3

0

Compute_scoreの各実行にかかる時間はわずか1ミリ秒ですが、T_comに10k要素、R_comに10k要素がある場合、これには10k * 10k *1msかかります。これは約27時間です。あなたが提示したように、これはO(n2)の問題です。ロジックを単純化できますか?できない場合は、他の手法が必要です。たとえば、並列実行や分散実行などです。

==編集==

コメントで説明したように、これはドット積です。それをO(n)に減らしてみてください。何かのようなもの:

scores = []
for index in T_com.keys():
    score = T_com[index] * R_com[index]
dot_product = sum(scores)
于 2012-07-04T03:15:23.450 に答える
0

その外観から、反復する各ディクショナリの各要素に対してツリーと新しいノードを作成しています。

スコアを計算するためにディクショナリの各要素を調べる必要がある場合、他の唯一のオプションは、各フィールドを繰り返す必要がないようにする計算を含む二次リソースを用意することです。

同様に、各ディクショナリの生成されたツリーのコピーを保持し、より多くの情報を取得して最終的にそれらをすべてリンクするように、それぞれに単純に追加することができます。

申し訳ありませんが、これをコメントとして残しておきましたが、コメントすることは許可されていないか、方法がわからないかもしれません...

とにかく、頑張ってください!

于 2012-07-04T03:05:50.953 に答える
0
score = compute_score(T_com[tar_node]tar_community,R_com[ref_node]ref_community)

これにより、辞書の検索時間を節約できますが、根本的な問題は x*y; です。これが本当に必要で、実行時間を気にする場合は、cython または純粋な C コードを使用して高速化することを検討してください。

于 2012-07-04T03:10:19.793 に答える