我想规范化Python字典的值,同时保持每个值的下限,其中下限由1 /(10 * n)给出,其中n是字典中值的数量。
字典d的值可以如下归一化。
from __future__ import division
d = {1:0.5, 2: 1.5, 3: 2.0, 4: 0.02, 5: 3.1}
total = sum(d.values())
d = {k: v / total for k, v in d.iteritems()}
print d
在这种情况下的下限是0.02
lb = 1 / (10 * len(d.keys()))
print lb
某些值小于归一化后的下限。问题是,如果我将小于lb的值设置为lb,则值的总和变得大于1。以下方法无效
D = dict(zip(d.keys(),[lb if i/total < lb else i/total for i in d.values()]))
print sum(D.values())
我们需要一种方法来重复规范化和设置lb,直到所有值都超过lb且值的总和为1。Python可以用什么方法解决此问题?
答案 0 :(得分:0)
下面的代码可以解决问题,但是我不确定它是最快还是最干净的方法。对于下面代码的任何改进,我将不胜感激。
from __future__ import division
Z = {1: 0.5, 2: 1.5, 3: 2.0, 4: 0.02, 5: 3.1}
total = sum(Z.values())
lb = 1 / (10 * len(Z.keys()))
print lb, "lower bound"
U = []
for k in Z.keys():
if Z[k] > lb:
U.append(k)
B = []
for k in Z.keys():
if Z[k] <= lb:
U.append(k)
def setBound():
count = 0
for k in U:
w = Z[k]
if w < lb:
Z[k] = lb
U.remove(k)
B.append(k)
count += 1
return count
def normalize():
bounded_sum = lb * len(B)
unbounded_sum = 0
for k in U:
unbounded_sum += Z[k]
multiple = (1-bounded_sum) / unbounded_sum
for k in U:
Z[k] *= multiple
def adjust():
normalize()
count = setBound()
if count > 0:
normalize()
return adjust()
else:
return
adjust()
print Z
print sum(Z.values()), "sum of all values"