鍍金池/ 問答/Python/ 檢索條件匹配句子的效率問題如何改進(jìn)?

檢索條件匹配句子的效率問題如何改進(jìn)?

需要寫個(gè)小腳本給不會(huì)編程的同事用,大致是他們自己編寫檢索條件然后去運(yùn)行腳本得出結(jié)果。

檢索條件類似這種:虛汗 or ((怕 or 畏) and (寒 or 冷))

目前試了兩種,in 方式( func1 )和正則匹配( func2 )
測(cè)試語(yǔ)料 1220 條,花費(fèi)時(shí)間:

func1 運(yùn)行時(shí)間:26.843648433685303

func2 運(yùn)行時(shí)間:46.992613554000854

當(dāng)語(yǔ)料很大,檢索條件量很多(或者嵌套很多)。效率感覺不怎么理想? 問問有沒思路改進(jìn)一下效率,或者有沒更好的方法思路。

相關(guān)代碼文件 鏈接: https://pan.baidu.com/s/1c2llxlu 密碼: v7ia

代碼下面貼出了自己寫的

# -*- coding=utf-8 -*-
import os
import re
import time
import pandas as pd
from pandas import DataFrame
from itertools import permutations


def str_to_list(p):
    """ 處理字符串轉(zhuǎn)換成列表
        如:虛汗 or ((怕 or 畏) and (寒 or 冷))
        結(jié)果:['虛汗','or',[['怕','or','畏'],'and',['寒','or','冷']]]
    """
    p = re.sub('([^\(\)()\s(?:and|or)]+|(?:and|or))','"\\1",',p)
    p = p.replace('(','[').replace('(','[').replace(')','],').replace(')','],')
    p = '[%s]' % p
    return eval(p)
    
def list_to_regex(p):
    """ 處理列表轉(zhuǎn)換成正則表達(dá)式
        遞歸方法
        如:['虛汗','or',[['怕','or','畏'],'and',['寒','or','冷']]]
        結(jié)果:(虛汗|((怕|畏).*?(寒|冷)|(寒|冷).*?(怕|畏)))
    """
    tempP = [list_to_regex(x) if isinstance(x,list) else x 
                for x in p 
                if x not in ['or','and']]
    if 'and' in p:
        tempP = permutations(tempP)  #生成排列
        return '(%s)' % '|'.join(['.*?'.join(x) for x in tempP])
    else:
        return '(%s)' % '|'.join(tempP)

def match_sentence(p,sentence):
    """轉(zhuǎn)成 in 的方式去匹配句子"""
    words = p.replace(' ','').replace(',','').replace('(','(').replace(')',')').replace('and',',and,').replace('or',',or,').replace('(',',(,').replace(')',',),').split(',')
    
    scriptStr = [w if w in 'and or ()' \
                    else '"%s" in "%s"' % (w,sentence) for w in words]
                    
    if eval(' '.join(scriptStr)):
        return True
    return False

def func1(patternFile,sentenceFile):
    """
    轉(zhuǎn)成正則再去匹配
    patternFile -- 含有檢索條件的文件名
    sentenceFile -- 語(yǔ)料文件名
    """
    dfS = pd.read_excel(sentenceFile)
    dfP = pd.read_excel(patternFile)
    #編譯好的正則列表
    regexList = [re.compile(list_to_regex(str_to_list(x))) for x in dfP.ix[:,-1]]
    resultFile = 'result1.txt'
    for senIdx in dfS.index:
        for i,patt in enumerate(regexList):
            keyword = dfP.ix[i,-2]
            sentence = dfS.ix[senIdx,-1]
            if patt.search(sentence):
                r = dfP.ix[[i],:-1]
                with open(resultFile,'a',encoding='utf-8') as f:
                    f.write('%s\t%s\n' % (keyword, sentence))
    
def func2(patternFile,sentenceFile):
    """
    轉(zhuǎn)成 in 的方式再去匹配
    patternFile -- 含有檢索條件的文件名
    sentenceFile -- 語(yǔ)料文件名
    """
    dfS = pd.read_excel(sentenceFile)
    dfP = pd.read_excel(patternFile)
    resultFile = 'result2.txt'
    for senIdx in dfS.index:
        for pattIdx in dfP.index:
            keyword = dfP.ix[pattIdx,-2]
            sentence = dfS.ix[senIdx,-1]
            if match_sentence(dfP.ix[pattIdx,-1],sentence):
                with open(resultFile,'a',encoding='utf-8') as f:
                    f.write('%s\t%s\n' % (keyword, sentence))
    
if __name__ == '__main__':
    """測(cè)試"""
    patternFile = '檢索條件_測(cè)試.xlsx'
    sentenceFile = '語(yǔ)料_測(cè)試.xlsx'
    t1 = time.time()
    func2(patternFile,sentenceFile)
    t2 = time.time()
    print('func2 運(yùn)行時(shí)間:',t2-t1)
回答
編輯回答
安于心
大致是他們自己編寫檢索條件然后去運(yùn)行腳本得出結(jié)果

部署一套現(xiàn)成的查詢引擎,比如 Elasticsearch https://www.elastic.co/produc...

2017年12月23日 20:14