【问题标题】:Quick implementation of character n-grams for word单词字符 n-gram 的快速实现
【发布时间】:2013-09-10 13:45:48
【问题描述】:

我编写了以下用于计算字符二元组的代码,输出如下所示。我的问题是,如何获得不包括最后一个字符(即 t)的输出?有没有更快更有效的计算字符 n-gram 的方法?

b='student'
>>> y=[]
>>> for x in range(len(b)):
    n=b[x:x+2]
    y.append(n)
>>> y
['st', 'tu', 'ud', 'de', 'en', 'nt', 't']

这是我想要得到的结果:['st','tu','ud','de','nt]

提前感谢您的建议。

【问题讨论】:

标签: python-2.7 n-gram


【解决方案1】:

要生成二元组:

In [8]: b='student'

In [9]: [b[i:i+2] for i in range(len(b)-1)]
Out[9]: ['st', 'tu', 'ud', 'de', 'en', 'nt']

泛化到不同的n

In [10]: n=4

In [11]: [b[i:i+n] for i in range(len(b)-n+1)]
Out[11]: ['stud', 'tude', 'uden', 'dent']

【讨论】:

    【解决方案2】:

    试试zip:

    >>> def word2ngrams(text, n=3, exact=True):
    ...   """ Convert text into character ngrams. """
    ...   return ["".join(j) for j in zip(*[text[i:] for i in range(n)])]
    ... 
    >>> word2ngrams('foobarbarblacksheep')
    ['foo', 'oob', 'oba', 'bar', 'arb', 'rba', 'bar', 'arb', 'rbl', 'bla', 'lac', 'ack', 'cks', 'ksh', 'she', 'hee', 'eep']
    

    但请注意它的速度较慢:

    import string, random, time
    
    def zip_ngrams(text, n=3, exact=True):
      return ["".join(j) for j in zip(*[text[i:] for i in range(n)])]
    
    def nozip_ngrams(text, n=3):
        return [text[i:i+n] for i in range(len(text)-n+1)]
    
    # Generate 10000 random strings of length 100.
    words = [''.join(random.choice(string.ascii_uppercase) for j in range(100)) for i in range(10000)]
    
    start = time.time()
    x = [zip_ngrams(w) for w in words]
    print time.time() - start
    
    start = time.time()
    y = [nozip_ngrams(w) for w in words]
    print time.time() - start        
    
    print x==y
    

    [出]:

    0.314492940903
    0.197558879852
    True
    

    【讨论】:

      【解决方案3】:

      这个函数为您提供 n = 1 到 n 的 ngram:

      def getNgrams(sentences, n):
          ngrams = []
          for sentence in sentences:
              _ngrams = []
              for _n in range(1,n+1):
                  for pos in range(1,len(sentence)-_n):
                      _ngrams.append([sentence[pos:pos+_n]])
              ngrams.append(_ngrams)
          return ngrams
      

      【讨论】:

        【解决方案4】:

        虽然晚了,但 NLTK 有一个实现 ngrams 的内置函数

        # python 3
        from nltk import ngrams
        ["".join(k1) for k1 in list(ngrams("hello world",n=3))]
        
        ['hel', 'ell', 'llo', 'lo ', 'o w', ' wo', 'wor', 'orl', 'rld']
        

        【讨论】:

          猜你喜欢
          • 2014-03-19
          • 2011-11-27
          • 1970-01-01
          • 1970-01-01
          • 2019-11-17
          • 2014-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多