我们可以为此使用正则表达式。我们将使用这个正则表达式
((?:\b\w+?\b\s*){0,3})[dD]ata((?:\s*\b\w+?\b){0,3})
你可以自己测试here,提取每次数据出现前后的三个词
首先,让我们从字符串中删除所有我们不喜欢的单词。
import re
# If you're processing a lot of sentences, it's probably wise to preprocess
#the pattern, assuming that bad_words is the same for all sentences
def remove_words(sentence, bad_words):
pat = r'(?:{})'.format(r'|'.join(bad_words))
return re.sub(pat, '', sentence, flags=re.IGNORECASE)
我们想要获取每行数据周围的单词
data_pat = r'((?:\b\w+?\b\s*){0,3})[dD]ata((?:\s*\b\w+?\b){0,3})'
res = re.findall(pat, s, flags=re.IGNORECASE)
给我们一个字符串元组的列表。我们希望在它们被拆分后得到这些字符串的列表。
from itertools import chain
list_of_words = list(chain.from_iterable(map(str.split, chain.from_iterable(map(chain, chain(res))))))
这并不漂亮,但它有效。基本上,我们将元组从列表中拉出,从每个元组中拉出字符串,然后拆分每个字符串,然后将所有字符串从它们最终进入的列表中拉出,形成一个大列表。
让我们将这些与您的pandas 代码放在一起。 pandas 不是我最擅长的领域,所以如果你看到一些奇怪的东西,请不要以为我没有犯一些基本的错误。
import re
from itertools import chain
from collections import Counter
def remove_words(sentence, bad_words):
pat = r'(?:{})'.format(r'|'.join(bad_words))
return re.sub(pat, '', sentence, flags=re.IGNORECASE)
bad_words = ['we', 'is', 'to']
sentence_list = df.Answer.apply(lambda x: remove_words(str(x), bad_words))
c = Counter()
data_pat = r'((?:\b\w+?\b\s*){0,3})data((?:\s*\b\w+?\b){0,3})'
for sentence in sentence_list:
res = re.findall(data_pat, sentence, flags=re.IGNORECASE)
words = chain.from_iterable(map(str.split, chain.from_iterable(map(chain, chain(res)))))
c.update(words)
我们使用的正则表达式的好处是所有复杂的部分都不关心我们使用的是什么词。稍作改动,我们可以制作一个格式字符串
base_pat = r'((?:\b\w+?\b\s*){{0,3}}){}((?:\s*\b\w+?\b){{0,3}})'
这样
base_pat.format('data') == data_pat
所以我们想通过一些单词列表来收集关于key_words的信息
import re
from itertools import chain
from collections import Counter
def remove_words(sentence, bad_words):
pat = r'(?:{})'.format(r'|'.join(bad_words))
return re.sub(pat, '', sentence, flags=re.IGNORECASE)
bad_words = ['we', 'is', 'to']
sentence_list = df.Answer.apply(lambda x: remove_words(str(x), bad_words))
key_words = ['data', 'analytics']
d = {}
base_pat = r'((?:\b\w+?\b\s*){{0,3}}){}((?:\s*\b\w+?\b){{0,3}})'
for keyword in key_words:
key_pat = base_pat.format(keyword)
c = Counter()
for sentence in sentence_list:
res = re.findall(key_pat, sentence, flags=re.IGNORECASE)
words = chain.from_iterable(map(str.split, chain.from_iterable(map(chain, chain(res)))))
c.update(words)
d[keyword] = c
现在我们有一个字典 d 映射关键字,例如 data 和 analytics 到 Counters 将不在我们黑名单上的单词映射到相关关键字附近的计数。像
d= {'data' : Counter({ 'important' : 2,
'very' : 3}),
'analytics' : Counter({ 'boring' : 5,
'sleep' : 3})
}
至于我们如何获得前 10 个单词,这基本上是 Counter 最擅长的。
key_words, _ = zip(*Counter(w for sentence in sentence_list for w in sentence.split()).most_common(10))