14

数値を持つ(非常に大きな)辞書があります。たとえば、data = {'a': 0.2, 'b': 0.3, ...}. これらの値を正規化する最良の方法は何ですか (編集: 値の合計が 1 になるようにしてください)。

そして、私が特に興味を持っているのは、特定のデータセットサイズに対して、辞書内包表記の代わりに numpy などを使用することは有益でしょうか?

私はpython 2.7を使用しています。

4

2 に答える 2

29

これを試して、その場で変更してください:

d={'a':0.2, 'b':0.3}
factor=1.0/sum(d.itervalues())
for k in d:
  d[k] = d[k]*factor

結果:

>>> d
{'a': 0.4, 'b': 0.6}

別の方法として、新しい辞書に変更するには、dict 内包表記を使用します。

d={'a':0.2, 'b':0.3}
factor=1.0/sum(d.itervalues())
normalised_d = {k: v*factor for k, v in d.iteritems() }

d.items() よりも少ないメモリを使用する d.iteritems() の使用に注意してください。したがって、大きな辞書には適しています。

編集:それらの数はかなり多く、これを正しく行うことが重要であるように思われるため、この回答へのコメントのすべてのアイデアをまとめて次のようにまとめました(この投稿から何かを借りることを含む):

import math
import operator

def really_safe_normalise_in_place(d):
    factor=1.0/math.fsum(d.itervalues())
    for k in d:
        d[k] = d[k]*factor
    key_for_max = max(d.iteritems(), key=operator.itemgetter(1))[0]
    diff = 1.0 - math.fsum(d.itervalues())
    #print "discrepancy = " + str(diff)
    d[key_for_max] += diff

d={v: v+1.0/v for v in xrange(1, 1000001)}
really_safe_normalise_in_place(d)
print math.fsum(d.itervalues())

正規化時に実際にゼロ以外のエラーを作成した辞書を思いつくために数回かかりましたが、これがポイントを示していることを願っています.

編集: Python 3.0 の場合。次の変更を参照してください: Python 3.0 Wiki組み込みの変更

dict.iteritems()、、dict.iterkeys()および を削除しdict.itervalues()ます。

代わりに、 それぞれdict.items()、 、 を使用してください。dict.keys()dict.values()

于 2013-05-07T11:37:06.787 に答える
4
def normalize(d, target=1.0):
   raw = sum(d.values())
   factor = target/raw
   return {key:value*factor for key,value in d.iteritems()}

次のように使用します。

>>> data = {'a': 0.2, 'b': 0.3, 'c': 1.5}
>>> normalize(data)
{'b': 0.15, 'c': 0.75, 'a': 0.1}
于 2013-05-07T11:40:57.327 に答える