Python中的频率分析 - 打印字母频率而非数字频率
s=array1 #user inputs an array with text in it
n=len(s)
f=arange(0,26,1)
import collections
dict = collections.defaultdict(int)
for c in s:
dict[c] += 1
for c in f:
print c,dict[c]/float(n)
在输出结果中,c是用数字表示的,而不是字母,我不太确定怎么把它转换回字母。
另外,有没有办法把频率和字母放进数组里,这样就可以把它们绘制成直方图了?
5 个回答
1
要把一个数字转换成它代表的字母,你只需要使用内置的 chr
函数就可以了:
>>> chr(98)
'b'
>>> chr(66)
'B'
>>>
3
如果你使用的是 Python 2.7 或更高版本,你可以使用 collections.Counter 这个工具。
Python 2.7 及以上版本
>>> import collections
>>> s = "I want to count frequencies."
>>> counter = collections.Counter(s)
>>> counter
Counter({' ': 4, 'e': 3, 'n': 3, 't': 3, 'c': 2, 'o': 2, 'u': 2, 'a': 1, 'f': 1, 'I': 1, 'q': 1, 'i': 1, 's': 1, 'r': 1, 'w': 1, '.': 1})
>>> n = sum(counter.values()) * 1.0 # Convert to float so division returns float.
>>> n
28
>>> [(char, count / n) for char, count in counter.most_common()]
[(' ', 0.14285714285714285), ('e', 0.10714285714285714), ('n', 0.10714285714285714), ('t', 0.10714285714285714), ('c', 0.07142857142857142), ('o', 0.07142857142857142), ('u', 0.07142857142857142), ('a', 0.03571428571428571), ('f', 0.03571428571428571), ('I', 0.03571428571428571), ('q', 0.03571428571428571), ('i', 0.03571428571428571), ('s', 0.03571428571428571), ('r', 0.03571428571428571), ('w', 0.03571428571428571), ('.', 0.03571428571428571)]
Python 3 及以上版本
>>> import collections
>>> s = "I want to count frequencies."
>>> counter = collections.Counter(s)
>>> counter
Counter({' ': 4, 'e': 3, 'n': 3, 't': 3, 'c': 2, 'o': 2, 'u': 2, 'a': 1, 'f': 1, 'I': 1, 'q': 1, 'i': 1, 's': 1, 'r': 1, 'w': 1, '.': 1})
>>> n = sum(counter.values())
>>> n
28
>>> [(char, count / n) for char, count in counter.most_common()]
[(' ', 0.14285714285714285), ('e', 0.10714285714285714), ('n', 0.10714285714285714), ('t', 0.10714285714285714), ('c', 0.07142857142857142), ('o', 0.07142857142857142), ('u', 0.07142857142857142), ('a', 0.03571428571428571), ('f', 0.03571428571428571), ('I', 0.03571428571428571), ('q', 0.03571428571428571), ('i', 0.03571428571428571), ('s', 0.03571428571428571), ('r', 0.03571428571428571), ('w', 0.03571428571428571), ('.', 0.03571428571428571)]
这个工具还会按照出现频率从高到低的顺序返回字符和它们的频率的组合。
4
需要指出的是,你没有用正确的参数调用 map 函数(所以出现了 TypeError
错误)。这个函数需要一个单独的函数和一个或多个可迭代对象,也就是你要对这些对象应用这个函数。你的第二个参数是 toChar[i],这实际上是一个字符串。所有的可迭代对象都实现了 __iter__
方法。举个例子:
>>> l, t = [], ()
>>> l.__iter__
<<< <method-wrapper '__iter__' of list object at 0x7ebcd6ac>
>>> t.__iter__
<<< <method-wrapper '__iter__' of tuple object at 0x7ef6102c>
DTing的回答让我想到了 collections.Counter:
>>> from collections import Counter
>>> a = 'asdfbasdfezadfweradf'
>>> dict((k, float(v)/len(a)) for k,v in Counter(a).most_common())
<<<
{'a': 0.2,
'b': 0.05,
'd': 0.2,
'e': 0.1,
'f': 0.2,
'r': 0.05,
's': 0.1,
'w': 0.05,
'z': 0.05}