使用 python 的二元函数

Bigram function using python

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

给定包含术语的列表列表,return 出现频率最高的 双字母组。 return 值应该是形式为 (bigram, count),降序排列,限于前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 函数最多列出两次输出。

如果数据适合内存,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 或更多的数据,您还打算做什么?对于这种 "big data" 情况,有一些可用的策略——一直到复杂的分布式方法(例如 mapreduce),再到基于合并和排序普通磁盘文件的简单单处理器方法。

如果你能更好地解释你的操作参数,我可以告诉更多有关适当的策略或策略。但从你的例子来看,"very large files" 对你的意义可能与对我的意义不同(数十或数百 GB 是中等大小——使用 "large" 这个词需要 TB 字节,并且超过“非常大”。

所以对于我上面给出的代码,调用会略有不同:

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

数字 2 排在第一位,因此所有其余参数都可以是一个列表(而不是必须使用不太优雅的列表列表)。但是,如果必须的话,切换 args 当然是微不足道的——只需将 def 语句更改为

def find_top_bigrams(manylists, n):

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

补充:特别地,输出似乎被限制为字符串而不是元组——微不足道的变化(尽管是对良好 CPU 周期的可怕浪费),只需更改

yield old, new

yield old + ' ' + new

或其他选择的格式化操作(但这是最简单的)。当然,有了这个微不足道的变化,结果就变成了 [('b c', 3), ('a b', 2)].