如何规范计数器并组合2个标准化计数器? - 蟒蛇

时间:2014-03-15 19:43:39

标签: python list counter

首先,我有两个字符串列表:

['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 :(得分:9)

您需要对这些值求和,然后将每个计数除以总和:

total = sum(x.values(), 0.0)
for key in x:
    x[key] /= total

通过使用0.0开始求和,我们确保total是一个浮点值,避免使用带有整数操作数的/的Python 2 floor划分行为。

演示:

>>> 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,例如。

答案 1 :(得分:0)

列表对象(c1)的计数器对象(l1)的规范化是将每个计数除以列表中总元素的数量,即列表的长度(total )。与计算c1之类的(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