中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python倒排索引之查找包含某主題或單詞的文件

發布時間:2020-09-06 17:12:30 來源:腳本之家 閱讀:173 作者:西西嘛呦 欄目:開發技術

什么是倒排索引?

倒排索引(英語:Inverted index),也常被稱為反向索引、置入檔案或反向檔案,是一種索引方法,被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射。它是文檔檢索系統中最常用的數據結構。通過倒排索引,可以根據單詞快速獲取包含這個單詞的文檔列表。倒排索引主要由兩個部分組成:“單詞詞典”和“倒排文件”。

假設我們現在有文件:

test1.txt中存有:我們愛自然語言處理

test2.txt中存有:我們愛計算機視覺

正向索引:

{“test1.txt”:["我們",“愛”,"自然語言","處理"],"test2.txt":["我們","愛","計算機","視覺"]}

那么,我們應該如何通過正向索引找到包含某詞語的文件呢?我們只能依次遍歷文件中的內容,從內容中找到是否有該詞語,正向查詢的效率很低。

倒排索引:

{"我們":["test1.txt","test2.txt"],"愛":["test1.txt","test2.txt"],"自然語言":["test1.txt"],"處理":["test1.txt"],"計算機":["test2.txt"],"視覺":["test2.txt"]}

建立倒排索引后,我們要想查找包含某些單詞的文件,直接從hash表中獲取,是不是就方便多了?接下來,我們用python實現:

現在有基本目錄:

Python倒排索引之查找包含某主題或單詞的文件

python.txt

Python的設計哲學是“優雅”、“明確”、“簡單”。因此,Perl語言中“總是有多種方法來做同一件事”的理念在Python開發者中通常是難以忍受的。Python開發者的哲學是“用一種方法,最好是只有一種方法來做一件事”。在設計Python語言時,如果面臨多種選擇,Python開發者一般會拒絕花俏的語法,而選擇明確的沒有或者很少有歧義的語法。由于這種設計觀念的差異,Python源代碼通常被認為比Perl具備更好的可讀性,并且能夠支撐大規模的軟件開發。這些準則被稱為Python格言。在Python解釋器內運行import this可以獲得完整的列表。
Python開發人員盡量避開不成熟或者不重要的優化。一些針對非重要部位的加快運行速度的補丁通常不會被合并到Python內。所以很多人認為Python很慢。不過,根據二八定律,大多數程序對速度要求不高。在某些對運行速度要求很高的情況,Python設計師傾向于使用JIT技術,或者用使用C/C++語言改寫這部分程序。可用的JIT技術是PyPy。
Python是完全面向對象的語言。函數、模塊、數字、字符串都是對象。并且完全支持繼承、重載、派生、多繼承,有益于增強源代碼的復用性。Python支持重載運算符和動態類型。相對于Lisp這種傳統的函數式編程語言,Python對函數式設計只提供了有限的支持。有兩個標準庫(functools, itertools)提供了Haskell和Standard ML中久經考驗的函數式程序設計工具。

java.txt

1.簡單性
Java看起來設計得很像C++,但是為了使語言小和容易熟悉,設計者們把C++語言中許多可用的特征去掉了,這些特征是一般程序員很少使用的。例如,Java不支持go to語句,代之以提供break和continue語句以及異常處理。Java還剔除了C++的操作符過載(overload)和多繼承特征,并且不使用主文件,免去了預處理程序。因為Java沒有結構,數組和串都是對象,所以不需要指針。Java能夠自動處理對象的引用和間接引用,實現自動的無用單元收集,使用戶不必為存儲管理問題煩惱,能更多的時間和精力花在研發上。
2.面向對象
Java是一個面向對象的語言。對程序員來說,這意味著要注意應中的數據和操縱數據的方法(method),而不是嚴格地用過程來思考。在一個面向對象的系統中,類(class)是數據和操作數據的方法的集合。數據和方法一起描述對象(object)的狀態和行為。每一對象是其狀態和行為的封裝。類是按一定體系和層次安排的,使得子類可以從超類繼承行為。在這個類層次體系中有一個根類,它是具有一般行為的類。Java程序是用類來組織的。
Java還包括一個類的擴展集合,分別組成各種程序包(Package),用戶可以在自己的程序中使用。例如,Java提供產生圖形用戶接口部件的類(java.awt包),這里awt是抽象窗口工具集(abstract windowing toolkit)的縮寫,處理輸入輸出的類(java.io包)和支持網絡功能的類(java.net包)。
3.分布性
Java設計成支持在網絡上應用,它是分布式語言。Java既支持各種層次的網絡連接,又以Socket類支持可靠的流(stream)網絡連接,所以用戶可以產生分布式的客戶機和服務器
網絡變成軟件應用的分布運載工具。Java程序只要編寫一次,就可到處運行。

c.txt

C語言是一種結構化語言,它有著清晰的層次,可按照模塊的方式對程序進行編寫,十分有利于程序的調試,且c語言的處理和表現能力都非常的強大,依靠非常全面的運算符和多樣的數據類型,可以輕易完成各種數據結構的構建,通過指針類型更可對內存直接尋址以及對硬件進行直接操作,因此既能夠用于開發系統程序,也可用于開發應用軟件。通過對C語言進行研究分析,總結出其主要特點如下:
(1)簡潔的語言
C語言包含有各種控制語句僅有9種,關鍵字也只有32 個,程序的編寫要求不嚴格且多以小寫字母為主,對許多不必要的部分進行了精簡。實際上,語句構成與硬件有關聯的較少,且C語言本身不提供與硬件相關的輸入輸出、文件管理等功能,如需此類功能,需要通過配合編譯系統所支持的各類庫進行編程,故c語言擁有非常簡潔的編譯系統。 [5]
(2)具有結構化的控制語句
C語言是一種結構化的語言,提供的控制語句具有結構化特征,如for語句、if⋯else語句和switch語句等。可以用于實現函數的邏輯控制,方便面向過程的程序設計。 [5]
(3)豐富的數據類型
C語言包含的數據類型廣泛,不僅包含有傳統的字符型、整型、浮點型、數組類型等數據類型,還具有其他編程語言所不具備的數據類型,其中以指針類型數據使用最為靈活,可以通過編程對各種數據結構進行計算。 [5]
(4)豐富的運算符
C語言包含34個運算符,它將賦值、括號等均視作運算符來操作,使C程序的表達式類型和運算符類型均非常豐富。 [5]
(5)可對物理地址進行直接操作
C語言允許對硬件內存地址進行直接讀寫,以此可以實現匯編語言的主要功能,并可直接操作硬件。C語言不但具備高級語言所具有的良好特性,又包含了許多低級語言的優勢,故在系統軟件編程領域有著廣泛的應用。 [5]
(6)代碼具有較好的可移植性
C語言是面向過程的編程語言,用戶只需要關注所被解決問題的本身,而不需要花費過多的精力去了解相關硬件,且針對不同的硬件環境,在用C語言實現相同功能時的代碼基本一致,不需或僅需進行少量改動便可完成移植,這就意味著,對于一臺計算機編寫的C程序可以在另一臺計算機上輕松地運行,從而極大的減少了程序移植的工作強度。 [5]
(7)可生成的高質量目標代碼,高執行效率的程序
復制代碼
首先,我們導入相應的包:

#用于獲取該目錄下得所有txt文件,忽略掉文件夾及里面的
import glob
#主要是一些路徑的操作
import os
#對句子進行分詞或關鍵詞提取
from jieba import analyse

Python倒排索引之查找包含某主題或單詞的文件

接下來,我們要獲取所有txt文件的絕對路徑:

#獲取當前pyhtho文件所在的目錄:當前是:C:\gongoubo\python-work\direc\files
dir_path = os.path.dirname(os.path.abspath(__file__))
print(dir_path)
#存儲txt文件的絕對路徑為列表,同時為每個文件建立索引
def file_store():
    files_name =[]
    files_dict = {}
    #獲取file文件夾下所有為txt的文件
    for i,name in enumerate(glob.glob("file/*.txt")):
        files_dict[i] = name.split('\\')[-1]
        file_name = dir_path + "\\" + name
        files_name.append(file_name)
    return files_name,files_dict

然后,我們讀取每個txt文件,再對其進行關鍵詞提取,將結果存儲到新的txt中,并用原txt文件的索引命名:

#讀取每個txt文件
def transform(files_name):
    #注意打開的時候需要申明為utf-8編碼
    for i,j in enumerate(files_name):
        #打開文件
        tmp = open(j,'r',encoding='utf-8').read()
        #提取關鍵詞
        content = analyse.extract_tags(tmp)
     #也可以進行分詞content=jieba.cut_for_search(tmp),關于jieba分詞,可以看我的自然語言處理之基礎技能
        #新建process文件夾
        path=dir_path+'\\file\\'+'process'
        if not os.path.exists(path):
            os.makedirs(path)
        #為存儲關鍵詞的txt取名,對應這每個文件的索引
        fp=open(path+'\\'+str(i)+'.txt','w',encoding='utf-8')
        #將關鍵詞寫入到txt中
        fp.write(" ".join(content))
        fp.close()

運行后,我們會有如下目錄:其中process文件夾下的是提取關鍵詞后的結果,文件名對應索引,即{0:"c.txt",1:"java.txt",2:"python.txt"}

 接下來,進行倒排索引的構建:

#建立倒排索引
def invert_index():
 path=dir_path+'\\file\\'+'process'
 word_dict = {}
 # 取包含關鍵詞的txt
 for file in glob.glob(path+'/*.txt'):
  #取出txt文件名,也就是文件的索引
  index = file.split('\\')[-1][0]
  #打開文件,并將關鍵詞存儲為列表
  with open(file,'r',encoding='utf-8') as fp:
   word_list=fp.read().split(" ")
  #建立倒排索引,如果單詞不在單詞字典中,就存儲文件的索引,否則就添加索引到索引列表后
  for word in word_list:
   if word not in word_dict:
    word_dict[word]=[index]
   else:
    word_dict[word].append(index)
 return word_dict

基本的內容我們有了,再考慮我們的輸入,我們希望實現在控制臺輸入幾個單詞,找到最符合的幾個文件。我們將輸入存儲為單詞列表,以此判斷該單詞是否出現在文件中,如果出現了,我們將該單詞對應的文件的索引+1,否則繼續判斷下一個單詞。之后我們得到了關于文件索引次數的字典,我們按次數從大到小排列,然后取前幾個作為我們最后的結果。當然,我們需要的是原始的文件名,因此,我們還要將索引映射回文件名,相關代碼如下:

def get_topk(count,topk=None):
 print(count)
 file_index = []
 #如果topk超出了返回的數目,則有多少顯示多少
 if topk > len(count):
  for i in range(0,len(count)):
   file_index.append(int(count[i][0]))
  return file_index
 if len(count)<0:
  print("沒有找到相關的文件")
  return False
 else:
  for i in range(0,topk):
   file_index.append(int(count[i][0]))
 return file_index

#得到文件名
def get_files(file_index,files_dict):
 res=[]
 for i in file_index:
  res.append(files_dict[i])
 return res

主函數:

def main():
 print("請輸入要查找的內容,不同單詞間','隔開:")
 words = input().split(',')
 #獲得文件名和文件名索引字典
 files_name, files_dict = file_store()
 #提取關鍵詞或分詞
 transform(files_name)
 #倒排索引建立
 word_dict = invert_index()
 count={}
 #統計文件索引的次數
 for word in words:
  if word in word_dict:
   for file in word_dict[word]:
    if file not in count:
     count[file]=1
    else:
     count[file]+=1
  else:
   continue
 #按次數從大到小排列
 count=sorted(count.items(),key=lambda i:i[1],reverse=True)
 #返回前k個文件索引
 file_index=get_topk(count,topk=3)
 if file_index != False:
  print("與之描述最可能的文件是:")
  #返回文件名,并輸出結果
  res=get_files(file_index,files_dict)
  print(res)

最后,我們運行主函數:

if __name__ == '__main__':
 main()

Python倒排索引之查找包含某主題或單詞的文件

最終結果:

我們將topk改為3:

Python倒排索引之查找包含某主題或單詞的文件

總結

以上所述是小編給大家介紹的Python倒排索引之查找包含某主題或單詞的文件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

岐山县| 旬邑县| 江都市| 曲沃县| 天峨县| 二连浩特市| 来凤县| 湛江市| 宜宾县| 分宜县| 大庆市| 徐闻县| 兴山县| 家居| 信阳市| 康乐县| 浠水县| 凉山| 吉林市| 龙口市| 剑川县| 中宁县| 隆林| 沧州市| 皮山县| 宜川县| 鄯善县| 汉寿县| 文登市| 修水县| 新绛县| 甘德县| 中江县| 曲沃县| 彭山县| 平阳县| 道真| 枣阳市| 平阴县| 罗山县| 克山县|