使用python在一大串概念字符串中查找输入字符串中的所有概念

时间:2018-06-28 22:55:10

标签: python performance list search substring

我在数据库中有大量的概念字符串(比如说3000万个)(每个字符串最多13个单词)。给定一个输入字符串(最多3个句子),我想从数据库中找到输入字符串中可用的所有概念。

我为此使用python。将数据库中的所有概念加载到列表中。循环浏览概念列表,并尝试在输入字符串中查找该概念是否可用。由于必须按顺序搜索它,因此该过程耗时很长,因此我将不得不为数百个输入字符串执行搜索。

为了修剪一些迭代,我标记了输入字符串,并尝试仅加载具有任何一个标记的概念,并且概念的长度必须小于或等于输入字符串的长度。它需要一个sql查询才能将这些简短列出的概念加载到列表中。列表仍然可能包含2000万个概念。这个过程不是那么快。

有人知道如何使这一过程更有效吗?

为了获得更好的可视化效果,我举了一个pythonic示例:

 inputString = "The cow is a domestic animal. It has four legs, one tail, two eyes"
#load concept list from the database that have any of the words in input string (after removing stop words). Assume the list is as follows.

concepts = ["cow", "domestic animal", "domestic bird", "domestic cat", "domestic dog", "one eye", "two eyes", "two legs", "four legs", "two ears"]

for c in concepts:
    if c in inputString:
        print ('found ' + c + ' in ' + inputString) 

如果您能给我一些建议使其更有效,那就太好了。

1 个答案:

答案 0 :(得分:1)

您应该使用集合,在查找项目时,集合比列表和全文本搜索要快得多。

将这些概念放入由单词数量索引的集合字典中。然后将inputString分成单词列表,然后使用此列表上单词数量的滚动窗口来测试这些单词是否存在于相同单词数量的索引集中。

因此进行了以下初始化:

from collections import defaultdict
import re
inputString = "The cow is a domestic animal. It has four legs, one tail, two eyes"
concepts = ["cow", "domestic animal", "domestic bird", "forever and ever", "practice makes perfect", "i will be back"]

我们将concepts分解为集合的字典,以集合中包含的概念的单词数为索引:

concept_sets = defaultdict(set)
for concept in concepts:
    concept_sets[len(concept.split())].add(concept)

这样concept_sets变为:

{1: {'cow'}, 2: {'domestic bird', 'domestic animal'}, 3: {'practice makes perfect', "forever and ever"}, 4: {'i will be back'}}

然后,我们将inputString变成小写单词列表,以便匹配不区分大小写。请注意,您可能要在此处优化正则表达式,以便它可以包含某些其他字符作为“单词”。

input_words = list(map(str.lower, re.findall(r'[a-z]+', inputString, re.IGNORECASE)))

最后,我们遍历concept_sets中的每个概念及其单词数量,并在相同数量单词的滚动窗口中从输入中浏览单词列表,并测试这些单词是否存在于集合。

for num_words, concept_set in concept_sets.items():
    for i in range(len(input_words) - num_words + 1):
        words = ' '.join(input_words[i: i + num_words])
        if words in concept_set:
            print("found '%s' in '%s'" % (words, inputString))

这将输出:

found 'cow' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'
found 'domestic animal' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'