1

我从一堆或电子邮件中读取数据并计算每个单词的频率。首先构造两个计数器:

counters.form = collections.defaultdict(dict)

获取频率

for word in re.findall('[a-zA-Z]\w*', data):
    counters.form[word][file_name] += 1

对于每个表单,都有一个计数器存储该单词出现的所有电子邮件,以及该表单在该电子邮件中出现的频率。例如

form = {'a':   {'email1':4, 'email2':3}, 
        'the': {'email1':2, 'email3':4},
        'or':  {'email1':2, 'email3':1}}

如何获取某封邮件中某个表格出现的频率?ain的频率email2为 3。

4

2 回答 2

2

使用Counter类而不是 a可能是个好主意defaultdict

Counter 是用于计算可散列对象的 dict 子类。它是一个无序集合,其中元素存储为字典键,它们的计数存储为字典值。计数可以是任何整数值,包括零计数或负计数。Counter 类类似于其他语言中的 bag 或 multisets。

于 2012-05-10T03:15:42.060 回答
2

看来您正在构建 IR(信息检索)社区所称的倒排索引。在这种情况下,我同意您采用的整体方法,但也建议您将 counter 类默认 dict 结合使用...

counters.form = collections.defaultdict(collections.Counter)

counters.form然后将充当压缩世界模型的一种索引,其中没有观察不是错误(也不是 False),只是 0。

以您的form数据为例,我们填充倒排索引,如...

#-- Build the example data into the proposed structure...
counters.form['a'].update({'email1':4, 'email2':3})
counters.form['the'].update({'email1':2, 'email3':4})
counters.form['or'].update({'email1':2, 'email3':1}})

现在,要获取此数据中表单的频率,我们将其取消引用,就像它是二维数组一样...

print counters.form['a']['email2']

...应该打印3并且与您当前使用的结构或多或少相同。这两种方法的真正区别在于您没有观察到的情况。例如...

print counters.form['noword']['some-email']

...使用您当前的结构 ( collections.defaultdict(dict)),获取 'noword' 上的counters.form'miss' 和 defaultdict 会自动将新建的空字典关联到counters.form['noword']; 然而,当这个空字典被查询键:'some-email'时,空字典没有这样的键,导致KeyError'some-email'的异常

相反,如果我们使用建议的结构 ( collections.defaultdict(collections.Counter)),那么 'noword' on 的 getcounters.form将丢失,并且 newcollections.Counter将与键 'noword' 相关联。当计数器被查询(在第二个取消引用中)'some-email'时,计数器将响应 0 - 这是(我相信)所需的行为。

其他一些食谱...

#-- Show distinct emails which contain 'someword'
emails = list(counters.form['someword'])

#-- Show tally of all observations of 'someword'
tally = sum(counters.form['someword'].values( ))
于 2012-05-10T04:55:08.660 回答