22

文字のバイグラムを計算するために次のコードを書きました。出力はすぐ下にあります。私の質問は、最後の文字 (つまり t) を除外した出力を取得するにはどうすればよいですか? 文字nグラムを計算するためのより迅速で効率的な方法はありますか?

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]

ご提案いただきありがとうございます。

4

4 に答える 4

43

バイグラムを生成するには:

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']
于 2013-09-06T12:47:12.710 に答える
10

試してください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
于 2014-03-15T17:15:15.847 に答える
1

遅くなりましたが、NLTK には ngram を実装する機能が組み込まれています

# 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']
于 2021-07-13T05:20:40.340 に答える