[英]python word grouping based on words before and after
我正在嘗試創建單詞組。 首先,我數所有單詞。 然后按字數確定前10個字。 然后,我想基於前10個單詞創建10個單詞組。每個組由位於該頂部單詞之前和之后的所有單詞組成。
我將調查結果存儲在這樣的python pandas數據框中
Question_ID | Customer_ID | Answer
1 234 Data is very important to use because ...
2 234 We value data since we need it ...
我還將答案列另存為字符串。
我正在使用以下代碼在一個單詞之前和之后找到3個單詞(實際上我必須在“答案”列中創建一個字符串)
answers_str = df.Answer.apply(str)
for value in answers_str:
non_data = re.split('data|Data', value)
terms_list = [term for term in non_data if len(term) > 0] # skip empty terms
substrs = [term.split()[0:3] for term in terms_list] # slice and grab first three terms
result = [' '.join(term) for term in substrs] # combine the terms back into substrings
print result
我一直在手動創建單詞組-但是在python中有辦法嗎?
因此,根據上面顯示的示例,帶有字數統計功能的組如下所示:
group "data":
data : 2
important: 1
value: 1
need:1
然后,當遍歷整個文件時,將出現另一組:
group "analytics:
analyze: 5
report: 7
list: 10
visualize: 16
這個想法也是要擺脫“我們”,“到”,“是”-但如果不可能的話,我可以手動完成。
然后建立10個最常用的單詞(按單詞計數),然后創建10個單詞組,這些單詞在最主要的前10個單詞的前面和后面。
我們可以為此使用正則表達式。 我們將使用此正則表達式
((?:\b\w+?\b\s*){0,3})[dD]ata((?:\s*\b\w+?\b){0,3})
您可以在此處進行自我測試,以提取每次出現數據前后的三個詞
首先,讓我們從字符串中刪除所有我們不喜歡的單詞。
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
類的關鍵字映射到Counter
,將不在我們的黑名單上的單詞映射到它們在相關關鍵字附近的計數。 就像是
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.