【问题标题】:Counting the Frequency of three words计算三个单词的频率
【发布时间】:2019-01-27 16:49:41
【问题描述】:

我有下面的代码来查找两个单词短语的频率。我需要对三个单词短语做同样的事情。

但是,下面的代码似乎不适用于 3 个单词的短语。

from collections import Counter
import re

sentence = "I love TV show makes me happy, I love also comedy show makes me feel like flying"
words = re.findall(r'\w+', sentence)
two_words = [' '.join(ws) for ws in zip(words, words[1:])]
wordscount = {w:f for w, f in Counter(two_words).most_common() if f > 1}
wordscount
{'show makes': 2, 'makes me': 2, 'I love': 2}

【问题讨论】:

    标签: python string python-3.x counter


    【解决方案1】:

    您可以在可迭代的 3 字分组上使用 collections.Counter。后者是通过生成器理解和列表切片构造的。

    from collections import Counter
    
    three_words = (words[i:i+3] for i in range(len(words)-2))
    counts = Counter(map(tuple, three_words))
    wordscount = {' '.join(word): freq for word, freq in counts.items() if freq > 1}
    
    print(wordscount)
    
    {'show makes me': 2}
    

    请注意,我们直到最后才使用str.join,以避免不必要的重复字符串操作。此外,Counter 需要 tuple 转换,因为 dict 键必须是可散列的。

    【讨论】:

      【解决方案2】:

      我建议将功能分解为a seperate function

      def nwise(iterable, n):
          """
          Iterate over n-grams of an iterable.
          Has a bit of an overhead compared to pairwise (although only during
          initialization), so the two functions are implemented independently.
          """
          iterables = [iter(iterable) for _ in range(n)]
          for index, it in enumerate(iterables):
              for _ in range(index):
                  next(it)
          yield from zip(*iterables)
      

      那你就可以了

      two_words = [" ".join(bigram) for bigram in nwise(words, 2))]
      

      three_words = [" ".join(trigram) for trigram in nwise(words, 3))]
      

      等等。 然后你可以在上面使用collections.Counter

      three_word_counts = Counter(" ".join(trigram) for trigram in nwise(words, 3))
      

      【讨论】:

      • 这很好。我只是觉得昂贵str.join 应该延迟到最小计数步骤的最终过滤。
      • @jpp 我怀疑这将是一个问题,但您也可以直接将nwise(words, 3) 输入计数器并按需提供str.join
      【解决方案3】:

      试试zip(words, words[1:], words[2:])

      例如:

      from collections import Counter
      import re
      
      sentence = "I love TV show makes me happy, I love also comedy show makes me feel like flying"
      words = re.findall(r'\w+', sentence)
      
      three_words = [' '.join(ws) for ws in zip(words, words[1:], words[2:])]
      wordscount = {w:f for w, f in Counter(three_words).most_common() if f > 1}
      print( wordscount )
      

      输出:

      {'show makes me': 2}
      

      【讨论】:

        【解决方案4】:

        怎么样:

        from collections import Counter
        
        sentence = "I love TV show makes me happy, I love also comedy show makes me feel like flying"
        words = sentence.split()
        r = Counter([' '.join(words[i:i+3]) for i in range(len(words)-3)])
        
        >>> r.most_common()[0] #get the most common 3-words
        ('show makes me', 2)
        

        【讨论】:

          猜你喜欢
          • 2023-03-22
          • 1970-01-01
          • 2015-01-07
          • 1970-01-01
          • 1970-01-01
          • 2015-06-06
          • 2013-12-28
          相关资源
          最近更新 更多