规范字典值

时间:2013-05-07 11:31:14

标签: python python-2.7

我有一个(非常大的)字典,它有数字值,例如data = {'a': 0.2, 'b': 0.3, ...}形式。标准化这些值的最佳方法是什么(编辑:确保值总和为1)?

我特别感兴趣的是:对于某些数据集大小,它是否有利于使用例如numpy而不是dict理解?

我正在使用python 2.7。

2 个答案:

答案 0 :(得分:18)

尝试此操作进行适当修改:

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}

或者修改成新词典,使用词典理解:

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.iteritems(),它使用的内存少于d.items(),因此对于大型字典更好。

编辑:由于他们中有很多人,并且这一点看起来很重要,我已将评论中的所有想法汇总到以下(包括借阅)来自this post)的内容:

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 Built-in Changes

  

删除dict.iteritems()dict.iterkeys()dict.itervalues()

     

相反:使用dict.items()dict.keys()dict.values()   分别

答案 1 :(得分: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}