我有一个嵌套python字典形式的完整倒排索引。其结构是:
{word:{doc_name:[location_list]}}
例如,让字典称为索引,然后对于单词“spam”,条目看起来像:
{spam:{doc1.txt:[102,300,399],doc5.txt:[200,587]}}
这样,包含任何单词的文档可以由 index [word] .keys()给出,并且该文档中的频率由 len(index [word] [document])给出
现在我的问题是,如何在此索引中实现常规查询搜索。即,给定一个包含4个单词的查询,找到包含所有四个匹配项的文档(按出现的总频率排列),然后是包含3个匹配项的文档,等等......
**
使用S. Lott的答案添加了此代码。 这是我写的代码。它完全按照我的意愿工作(只需要输出一些格式)但我知道它可以改进。
**
from collections import defaultdict
from operator import itemgetter
# Take input
query = input(" Enter the query : ")
# Some preprocessing
query = query.lower()
query = query.strip()
# now real work
wordlist = query.split()
search_words = [ x for x in wordlist if x in index ] # list of words that are present in index.
print "\nsearching for words ... : ", search_words, "\n"
doc_has_word = [ (index[word].keys(),word) for word in search_words ]
doc_words = defaultdict(list)
for d, w in doc_has_word:
for p in d:
doc_words[p].append(w)
# create a dictionary identifying matches for each document
result_set = {}
for i in doc_words.keys():
count = 0
matches = len(doc_words[i]) # number of matches
for w in doc_words[i]:
count += len(index[w][i]) # count total occurances
result_set[i] = (matches,count)
# Now print in sorted order
print " Document \t\t Words matched \t\t Total Frequency "
print '-'*40
for doc, (matches, count)) in sorted(result_set.items(), key = itemgetter(1), reverse = True):
print doc, "\t",doc_words[doc],"\t",count
请评论.... 感谢名单。
答案 0 :(得分:3)
这是一个开始:
doc_has_word = [ (index[word].keys(),word) for word in wordlist ]
这将构建(单词,文档)对的列表。你不能轻易地制作一本字典,因为每个文档都会多次出现。
但是
from collections import defaultdict
doc_words = defaultdict(list)
for d, w in doc_has_word:
doc_words[tuple(d.items())].append(w)
可能会有所帮助。
答案 1 :(得分:0)
import itertools
index = {...}
def query(*args):
result = []
doc_count = [(doc, len(index[word][doc])) for word in args for doc in index[word]]
doc_group = itertools.groupby(doc_count, key=lambda doc: doc[0])
for doc, group in doc_group:
result.append((doc, sum([elem[1] for elem in group])))
return sorted(result, key=lambda x:x[1])[::-1]
答案 2 :(得分:0)
这是寻找类似文件(最难的部分)的解决方案:
wordList = ['spam','eggs','toast'] # our list of words to query for
wordMatches = [index.get(word, {}) for word in wordList]
similarDocs = reduce(set.intersection, [set(docMatch.keys()) for docMatch in wordMatches])
wordMatches
获取一个列表,其中每个元素都是文档的字典,匹配其中一个匹配的单词。
similarDocs
是一组包含所查询的所有单词的文档。只需从wordMatches
列表中的每个字典中取出文档名称,将这些文档名称列表作为集合,然后将这些集合相交以查找公共文档名称即可找到。
一旦找到相似的文档,您应该能够使用defaultdict(如S. Lott的答案中所示)将所有匹配列表附加到每个单词和每个文档中。
相关链接: