我有一个(相当大的)字典,其中包含数值,例如以data = {'a': 0.2, 'b': 0.3, ...}
. 标准化这些值的最佳方法是什么(编辑:确保值总和为 1)?
我特别感兴趣的是:对于某些数据集大小,使用例如 numpy 而不是 dict 理解是否有益?
我正在使用python 2.7。
我有一个(相当大的)字典,其中包含数值,例如以data = {'a': 0.2, 'b': 0.3, ...}
. 标准化这些值的最佳方法是什么(编辑:确保值总和为 1)?
我特别感兴趣的是:对于某些数据集大小,使用例如 numpy 而不是 dict 理解是否有益?
我正在使用python 2.7。
试试这个修改到位:
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() 使用更少的内存,因此更适合大型字典。
编辑:由于其中有很多,并且做到这一点似乎很重要,因此我将对此答案的评论中的所有想法汇总到以下内容(包括从这篇文章中借用一些东西):
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()
。
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}