IR中python 写倒排索引与查询处理

学习信息检索课程,老师让写一个倒排索引与查询处理的程序,于是抱着试试的心态自学python写了出来。

整个没有什么太大的算法技巧,唯一的就是查询处理那里递归函数正反两次反复查找需要多调试下。

数据结构:

#-*-coding:utf-8-*-
#!/usr/bin/python

'''
数据结构
建立索引
mydir   文档列表
onedoc  每一个文档
mydoc   当前查询的文档

mywords 建立索引的字典
myindex 0 文档下标 1 单词下标 2 次数 3...
wordcntdict中的个数 doccnt文档个数

三个字典
mywordsdictindex  单词编号 起始位置
antimywordsdict   单词编号 结束位置
mywordsdict       单词->单词编号

查询
mypos是每个的单词起始的index下标
myfindindex是每个单词的标号,
mydocs 查询到的文档号

'''
mydir=[]
mywords=[]
myindex=[]

mywordsdictindex={}
antimywordsdict={}
mywordsdict={}

wordcnt=0#dict中的个数
doccnt=0#文档个数
listcnt=0#index个数

mypos=[]
mydocs=[]
myfindindex=[]

mydoc=0
direct=0
print id(mydir)

创建索引:

#-*-coding:utf-8-*-
#!/usr/bin/python

from mydate import *
import sys
import os
import pprint
import pickle
def getmydoc(thepath,onedir):
	ans=[]
	for line in open(thepath+'/'+onedir):
		line=line.strip('\n')
		ans.append(line)
	return ans

def createindex(thepath):
	global mydir
	global mywords
	global myindex
	global mywordsdictindex
	global antimywordsdict
	global mywordsdict
	global wordcnt
	global doccnt
	global listcnt
	global mypos
	global mydocs
	global myfindindex
	global mydoc
	global direct
	mydir=os.listdir(thepath)
	for i in mydir:
		if(os.path.isdir(thepath+'/'+i)==True):
			mydir.remove(i)
	#print mydir
	mydir=['a.txt','b.txt','c.txt']
	wordcnt=0#dict中的个数
	doccnt=0#文档个数
	listcnt=0#index个数
	print id(wordcnt)
	for onedoc in mydir:
		mylist=getmydoc(thepath,onedoc)
		onedocword=0#每个词在这个文本中的位置
		docworddict={}
		for myword in mylist:
			if(myword not in mywordsdict):
				mywords.append([0]*2)
				mywords[wordcnt][0]=myword
				mywordsdict[myword]=wordcnt
				wordcnt+=1
				#print myword,mywordsdict[myword]
			if(myword not in docworddict):
				docworddict[myword]=listcnt
				listcnt+=1
				myindex.append([0]*3)
			ins=docworddict[myword]
			myindex[ins][0]=doccnt
			myindex[ins][1]=mywordsdict[myword]
			myindex[ins][2]+=1
			myindex[ins].append(onedocword)
			onedocword+=1
		doccnt+=1
	myindex.sort(key=lambda x:x[1]) #sort
	beg=0
	fin=0
	for i in range(len(mywords)):
		mywordsdictindex[mywords[i][0]]=beg
		mywords[i][1]=beg
		while fin <len(myindex) and myindex[fin][1]==i:#python不支持逻辑短路
			fin+=1
		beg=fin
	for i in range(len(mywords)):
		mywordsdictindex[i]=mywords[i][1]
		if(i==len(mywords)-1):
			antimywordsdict[i]=len(myindex)
		else:
			antimywordsdict[i]=mywords[i+1][1]
'''
	pprint.pprint (mywords)
	pprint.pprint (myindex)
	pprint.pprint (mywordsdict)
	pprint.pprint (mywordsdictindex)
	pprint.pprint (antimywordsdict)

	out=open("myindex.dat","wb")
	pickle.dump(myindex,out)
	out=open("mywords.dat","wb")
	pickle.dump(mywords,out)
'''

接收查询与查询处理:

#-*-coding:utf-8-*-
#!/usr/bin/python
#得到一个文本的列表
import sys
import os
import pprint
import pickle
import pdb
from mydate import *
'''
返回值三种:1 整个查询词都找到了 0 并没有同时出现在一个文本中 -1 查询完毕或不存在
mydoc 查询词是否都在这个文档中
direct 查询方向 direct=0 递归向下,携带标记flag若为1则表明之前一直存在。0表明并不都在一个文本中那么mydoc取过程中的最大值
      当到len(mypos)的时候,决定是否将该结果放入,并将最后一个词的mypos后移 改变查询方向,并返回1
      direct=1 递归返回,与0同样操作,当到第0层再改变查询方向
'''
def findword(loc,flag):
	global mydir
	global mywords
	global myindex
	global mywordsdictindex
	global antimywordsdict
	global mywordsdict
	global wordcnt
	global doccnt
	global listcnt
	global mypos
	global mydocs
	global myfindindex
	global mydoc
	global direct
	if(loc==len(mypos)):
		#pdb.set_trace()
		direct=1#############################
		if(flag==1):
			mydocs.append(mydoc)
			i=mypos[loc-1]+1
			#print mydocs
			if(i<antimywordsdict[myfindindex[loc-1]]):
				mydoc=myindex[i][0]
			else:
				return -1
		return 1
	i=mypos[loc]
	while i<antimywordsdict[myfindindex[loc]]:
		if(flag==-1):
			return -1
		if(loc==0 and direct==1):
			direct=0
		if( flag==1 and loc==0):
			mydocs.append(mydoc)#############################
			i+=1
			#print mydocs
			if(i<antimywordsdict[myfindindex[loc]]):
				mydoc=myindex[i][0]
			else:
				return 0
		T=0
		while i<antimywordsdict[myfindindex[loc]] and myindex[i][0]<=mydoc:
			if(myindex[i][0]==mydoc):
				T=1
				break
			i+=1
		if(T==0):
			if(i+1==antimywordsdict[myfindindex[loc]]):
				return -1
			i+=1
			mydoc=myindex[i][0]
		mypos[loc]=i#############################
		if(flag==1 and T==1):
			pass
		else:
			T=0
		if(direct==1):
			return T
		flag=findword(loc+1,T)
	return 0

def getwords():
	global mydir
	global mywords
	global myindex
	global mywordsdictindex
	global antimywordsdict
	global mywordsdict
	global wordcnt
	global doccnt
	global listcnt
	global mypos
	global mydocs
	global myfindindex
	global mydoc
	global direct
	searchword=raw_input("find words\n")
	searchword=searchword.split(' ')
	flag=True
	for i in range(len(searchword)):
		if(searchword[i] not in mywordsdict):
			flag=False
			break
		myfindindex.append(mywordsdict[searchword[i]])#mypos是每个的单词起始的index下标,myfindindex是每个单词的标号,三个字典
		mypos.append(mywordsdictindex[searchword[i]])

	if(flag==False):
		print 'wrong'
		sys.exit()
	mydoc=myindex[mywordsdictindex[myfindindex[0]]][0]
	direct=0

	import pdb
	#pdb.set_trace()
	flag=findword(0,0)
	print mydocs#mydocs 查询到的文档号 返回这个数据

使用:

#-*-coding:utf-8-*-
#!/usr/bin/python
import hwf
from mydate import *
import createindex
import sys
import os
import pprint
import pickle

createindex.createindex('.')#创建索引
hwf.getwords()#查询单词
时间: 2024-08-17 12:00:16

IR中python 写倒排索引与查询处理的相关文章

使用python写自动执行脚本并将结果返回到html中

终于在今天完成了django项目开发的一个小项目,使用python写一个自动化上线的项目.使用到了python3.5,django 1.11.2,ansible,centos7. 功能描述如下: 1.使用网页点击要上线的项目 2.在后台系统执行过程中浏览器等待后台命令调用 3.在上线完成后将后台执行的结果回传到浏览器中. 步骤解说: 1.在django中要分清楚get和post的请求方式 2.使用subprocess.Popen调用时stdout时是byes类型需要使用str(stdout,en

10 行 Python 代码实现模糊查询/智能提示

10 行 Python 代码实现模糊查询/智能提示 1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P) Sublime Text (Cmd-P) '模糊匹配'这是一个极为有用的特性,同时也非常易于实现. 2.问题分析: 我们有一堆字符串(文件名)集合,我们根据用户的输入不断进行过滤,用户的输入可能是字符串的一部分.我们就以下面的

【python爬虫】根据查询词爬取网站返回结果

最近在做语义方面的问题,需要反义词.就在网上找反义词大全之类的,但是大多不全,没有我想要的.然后就找相关的网站,发现了http://fanyici.xpcha.com/5f7x868lizu.html,还行能把"老师"-"学生","医生"-"病人"这样对立关系的反义词查出来. 一开始我想把网站中数据库中存在的所有的词语都爬出来(暗网爬虫),但是分析了url的特点: http://fanyici.xpcha.com/5f7x86

Python写的CSDN信息推送小助手

转载请注明出处:http://blog.csdn.net/gamer_gyt 博主微博:http://weibo.com/234654758 Github:https://github.com/thinkgamer 前言 这几天突然萌生了一个想法:自己写个python程序,定时查询一下自己的CSDN博客的一些信息,并以邮件的形式推送给自己,那么废话不多说,现在已经把基本功能给实现了,每天可以定时发送访问量,积分,排名,同时会比较前一天的数据,形成对比,呈现给自己,这样就能一目了然的看到自己每天博

【转】用Python写了个金融数据爬虫,半小时干了全组一周的工作量

用Python写了个金融数据爬虫,半小时干了全组一周的工作量 原创kk12345677 最后发布于2019-08-21 16:59:54 阅读数 1652 收藏 展开 最近,越来越多的研究员.基金经理甚至财务会计领域的朋友,向小编咨询:金融人需要学Python么? 事实上在2019年,这已经不是一个问题了.Python已成为国内很多顶级投行.基金.咨询等泛金融.商科领域的必备技能.中金公司.银河证券.南方基金.银华基金在招聘分析师岗位时,纷纷要求熟练掌握Python数据分析技能. Excel我已

caffe 中 python 数据层

caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. 如在fcn 的voc_layers.py 中 有两个类: VOCSegDataLayer SBDDSegDataLayer 分别包含:setup,reshape,forward, backward, load_image, load_label. 不需要backward 没有参数更新. import

python 写的http后台弱口令爆破工具

# -*- coding: utf-8 -*- # 利用python 写的多线程爆破后台用户名+密码(自备字典),比较实用,即使是在信息安全这么重视的今天,还是有人不加验证码或者异常访问限制之类的登陆验证方式,这样就很# 容易被弱口令爆破工具拿下,(本代码仅限学习实用,禁止进行web攻击,不承担法律责任) import urllib2 import urllib import httplib import threading headers = {"Content-Type":&quo

作业1+2.四则运算(改进后完整版,用python写的)_064121陶源

概述: 用一个星期加上五一的三天假期自学了python,在Mac系统上重新写出了四则运算的程序,编译器是PyCharm,相当于完成了作业2.d)"选一个你从来没有学过的编程语言,试一试实现基本功能"这个方向. 用python写的这个程序能实现分数的加减程序,实现带加减乘除和括号的计算题,实现随机生成100道简单计算题,比之前用C++写的程序功能更加完善,更加简洁! 关键点: 调用两个模板. 1)类似C++和Java,格式是 对象.方法(),Fraction()方法,能直接表示分数. 2

SecureCRT中python脚本编写

SecureCRT中python脚本编写学习指南 SecureCRT python 引言 在测试网络设备中,通常使用脚本对设备端进行配置和测试以及维护:对于PE设备的测试维护人员来说使用较多是SecureCRT工具:SecureCRT支持VB.JavaScript.Python等多种脚本语言,为了实现脚本在CRT中更加丰富稳定地执行,掌握CRT的常用函数是非常有用的.接下来的时间我将对SecureCRT脚本编写的常用函数展开学习应用. 内容 (1)使用python语言实现SecureCRT中的D