如何对计数器进行归一化并合并两个归一化的计数器? - python
首先,我有两个字符串列表:
['abc','abc','def','jkl']
['abc','def','def','pqr', 'pr', 'foo', 'bar']
然后我需要对这些列表进行计数,使得每个计数器中的值加起来等于1:
Counter({'abc': 0.8164965809277261, 'jkl': 0.4082482904638631, 'def': 0.4082482904638631})
Counter({'abc': 1.1498299142610595, 'def': 1.0749149571305296, 'jkl': 0.4082482904638631, 'pr': 0.3333333333333333, 'bar': 0.3333333333333333, 'pqr': 0.3333333333333333, 'foo': 0.3333333333333333})
归一化的因子是
math.sqrt(sum(i*i for i in counter.values()))
我尝试过通过遍历计数器的键来实现,但有没有其他方法可以得到像 x+y
这样的计数器呢?
>>> from collections import Counter
>>> import math
>>> x = Counter(['abc','abc','def','jkl'])
>>> denominator = 1/math.sqrt(sum(math.pow(i,2) for i in x.values()))
>>> for i in x:
... x[i]*=denominator
...
>>> x
Counter({'abc': 0.8164965809277261, 'jkl': 0.4082482904638631, 'def': 0.4082482904638631})
>>> y = Counter(['abc','def','def','pqr', 'pr', 'foo', 'bar'])
>>> denominator2 = 1/math.sqrt(sum(math.pow(i,2) for i in y.values()))
>>> for i in y:
... y[i]*=denominator2
...
>>> y
Counter({'def': 0.6666666666666666, 'pr': 0.3333333333333333, 'abc': 0.3333333333333333, 'bar': 0.3333333333333333, 'pqr': 0.3333333333333333, 'foo': 0.3333333333333333})
>>> x+y
Counter({'abc': 1.1498299142610595, 'def': 1.0749149571305296, 'jkl': 0.4082482904638631, 'pr': 0.3333333333333333, 'bar': 0.3333333333333333, 'pqr': 0.3333333333333333, 'foo': 0.3333333333333333})
2 个回答
0
对一个计数器对象(c1
)进行归一化处理,就是把每个计数值除以列表中元素的总数,也就是列表的长度(total
)。这样做比直接计算计数器中所有计数的总和(像是用sum(c1.values(), 0.0)
)要省事得多。
下面的例子可以用来说明第一个给定的列表:
l1 = ['abc','abc','def','jkl']
c1 = Counter(l1)
# Normalization
total = 1.0 * len(l1) # converting to float to avoid floor division in Python 2.X
for k in c1:
c1[k] /= total
17
你需要先把所有的数加起来,然后再把每个计数除以这个总和:
total = sum(x.values(), 0.0)
for key in x:
x[key] /= total
我们从 0.0
开始加总,这样可以确保 total
是一个浮点数,避免在 Python 2 中用整数做除法时出现向下取整的情况。
演示:
>>> from collections import Counter
>>> x = Counter(['abc','abc','def','jkl'])
>>> total = sum(x.values(), 0.0)
>>> for key in x:
... x[key] /= total
...
>>> x
Counter({'abc': 0.5, 'jkl': 0.25, 'def': 0.25})
>>> y = Counter(['abc','def','def','pqr', 'pr', 'foo', 'bar'])
>>> total = sum(y.values(), 0.0)
>>> for key in y:
... y[key] /= total
...
>>> y
Counter({'def': 0.2857142857142857, 'pr': 0.14285714285714285, 'abc': 0.14285714285714285, 'bar': 0.14285714285714285, 'pqr': 0.14285714285714285, 'foo': 0.14285714285714285})
如果你需要把计数器的值相加,你还需要单独重新调整结果计数器的值;因为把两个已经调整过的计数器相加,可能会得到一个新的计数器,它的总值是 2,比如说。