Bigram函数使用python

时间:2015-02-02 03:28:26

标签: python list count

我想用python计算文件中所有bigrams(一对相邻单词)的出现次数。在这里,我正在处理非常大的文件,所以我正在寻找一种有效的方法。我尝试在文件内容上使用带有正则表达式“\ w + \ s \ w +”的count方法,但它没有被证明是有效的。

鉴于包含术语的列表列表,返回最频繁     二元语法。返回值应该是表单中的元组列表(bigram,     数量),按降序排列,仅限于前n个双子座。在示例中     下面提供了两份文件;前两位的双子座是'b c'(3     发生)和'a b'(2次出现)。 这就是我尝试过的,但它列出了所有双字母的数量..

from itertools import tee, islice
def find_top_bigrams(terms,n):
    tlst = terms
    while True:
        a, b = tee(tlst)
        l = tuple(islice(a, n))
        if len(l) == n:
          yield l
          next(b)
          tlst = b
        else:
          break


find_top_bigrams([['a', 'b', 'c', 'd'], ['b', 'c', 'a', 'b', 'c']], 2)
>>[('b c', 3), ('a b', 2)]

我希望find_top_bigrams函数列出最多两个输出事件。

1 个答案:

答案 0 :(得分:2)

如果数据适合内存,collections.Counter就是你的朋友。

import collections

def list_to_bigrams(somelist):
    it = iter(somelist)
    old = next(it, None)
    for new in it:
        yield old, new
        old = new

def find_top_bigrams(n, *manylists):
    c = collections.Counter()
    for somelist in manylists:
        c.update(list_to_bigrams(somelist))
    return c.most_common(n)

如果数据太大而无法容纳在内存中,那么你将不得不在磁盘上工作 - 速度要慢得多,但是,对于几十GB或更多,你还要做什么?对于这种“大数据”情况,有一些可行的策略 - 一直到复杂的分布式方法,例如mapreduce,基于合并和排序普通磁盘文件的简单单处理器方法。

如果您能更好地解释您的操作参数,我可以详细说明适当的策略或策略。但是从你的例子中可以看出,“非常大的文件”对我来说可能并不意味着对我来说(数十或数百GB是中等大小的 - 使用“大”字需要太字节,等等而不是“非常大”)。

因此,使用上面提到的代码,调用会略有不同:

find_top_bigrams(2, ['a', 'b', 'c', 'd'], ['b', 'c', 'a', 'b', 'c'])
[(('b', 'c'), 3), (('a', 'b'), 2)]

首先是数字2,所以其余所有参数都可以是一个列表(而不是必须使用不太优雅的列表列表)。但是,如果必须,只需将def语句更改为

,就可以轻松切换args
def find_top_bigrams(manylists, n):

你可以完全使用你在示例中给出的调用语法,而我上面提到的其余代码保持不变。

补充说:特别是输出似乎被限制为字符串而不是元组 - 微不足道的变化(尽管浪费了很好的CPU周期),只是改变

yield old, new

yield old + ' ' + new

或其他选择的格式化操作(但这是最简单的)。当然,通过这种微不足道的改变,结果变为[('b c', 3), ('a b', 2)]