用于词对共现计数的高效 Python?

Int*_*ing 5 python pandas natural-language-processing

我想要一种有效的 Pythonic 方法来计算文本中的相邻单词对。高效,因为它需要处理更大的数据集。

计数的方式也很重要。

考虑这个简化的例子:

words_list = "apple banana banana apple".split()
Run Code Online (Sandbox Code Playgroud)

我可以使用以下方法创建相邻对:

word_pair_list = zip(words_list[:-1], words_list[1:])
Run Code Online (Sandbox Code Playgroud)

然后我可以使用 Python 计算它们

word_pair_ctr = collections.Counter(word_pair_list)
Run Code Online (Sandbox Code Playgroud)

这给了我

(('apple', 'banana'), 1)
(('banana', 'banana'), 1)
(('banana', 'apple'), 1)
Run Code Online (Sandbox Code Playgroud)

请注意,'apple''apple'不是相邻对。

但我希望对的顺序不计算在内。这意味着('apple', 'banana')('banana', 'apple')应该被认为是相同的,并且计数应该是

(('apple', 'banana'), 2)
(('banana', 'banana'), 1)
Run Code Online (Sandbox Code Playgroud)

我找不到一种不需要我访问单词列表中的每个项目的 Pythonic 方法,这对于较大的文本来说效率很低。

我也很高兴使用常见的 scipy、numpy 和 pandas 作为库。

小智 2

您可以使用官方文档(https://docs.python.org/3.8/library/itertools.html)中的pairwise函数的修改版本,以便按对读取列表,同时对成员重新排序每对的:

l = "apple banana banana apple".split()
def pairwise(iterable):
    """s -> (s0,s1), (s1,s2), (s2, s3), ..."""
    a, b = itertools.tee(iterable)
    next(b, None)
    return ((a, b) if a < b else (b, a) for a, b in zip(a, b))
>>> list(pairwise(l))
<class 'list'>: ['apple', 'banana', 'banana', 'apple']
>>> collections.Counter(pairwise(l))
Counter({('apple', 'banana'): 2, ('banana', 'banana'): 1})
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!