【问题标题】:python operator 'in' versus regular expressionspython运算符'in'与正则表达式
【发布时间】:2017-11-02 11:29:42
【问题描述】:

我正在研究医学术语数据库(mesh 和 uniprot),并且我正在解析大量医学论文(已发布),以搜索论文中的术语匹配。这两个数字都非常惊人(约 30 万个术语和约 650 万篇论文),因此匹配算法必须尽可能高效。

目前我正在做这样的事情:

foo = "some long and boring medical paper [...] that I'm searching"
bar = [["array of medical terms matched with an unique code",1],
       ["also they are sorted by length",2]]
for term in bar:
    if term[0] in foo:
        repetitions = foo.count(term[0])
        array_to_be_inserted_in_database.append(term[1],repetitions) 

注意:foo 来自 NLTK 语料库生成器(为了保持示例简单而省略),array_to_be_inserted_in_database 顾名思义;当我完成bar 检查后,我将所有内容保存在 MongoDB 中并准备下一篇论文。

问题:

我不太习惯正则表达式,它们在速度方面值得吗?化合物和医学术语也充满了转义字符(例如:(1-5)-methylbuthyl*-ethyl-something),您如何“中和”它们,以免它们干扰 RE?

编辑:自我回答 经过一些研究和测试,in 比 REs 快

t= timeit.Timer(
    're.subn(regex,"",frase)',
    setup = 'import re; frase = "el gato gordo de la abuela"; palabra = "gordo"; regex = re.compile(palabra)'


    )
ordenes = """\
if palabra in frase:
    numero = frase.count(palabra)
    frase.replace(palabra,"")
"""
y= timeit.Timer(stmt= ordenes,setup = 'frase = "el gato gordo de la abuela"; palabra = "gordo"'
    )

print t.timeit(number = 1000)
print y.timeit(number = 1000)

【问题讨论】:

    标签: python regex python-2.7


    【解决方案1】:

    如果您只处理逐字字符串(而不是模式),并且如果您不介意gut 之类的术语也可以匹配gutter 之类的较长单词,那么in 可能会更快.

    另一方面,您可以使用re.findall() 一次完成所有匹配并获取结果列表的长度,因此您不必遍历字符串两次(一次用于查找,一次用于计数)。中和特殊字符很容易 - 只需在字符串上调用 re.escape(),它将确保文本按原样匹配。

    最后,唯一可以肯定的方法是根据真实数据测试这两种解决方案。

    【讨论】:

    • 我用真实世界的数据做了一些测试,REs 比多次遍历字符串要慢
    【解决方案2】:

    您可以在所有论文上创建索引,列出哪些单词出现在哪些论文中,然后只搜索包含所有相关单词的论文,而不是单独搜索所有术语。这样,您必须扫描每篇论文一次以建立索引,然后您只需对那些您知道它们包含所有相关术语的论文进行全文搜索。

    非常简单的伪代码:

    # get interesting words
    interesting_words = set(word for term in terms for word in term.split())
    
    # build index, mapping interesting words to papers they appear in
    index = defaultdict(set)
    for paper in papers:
        for word in paper.text:
            if word in interesting_words:
                index[word].add(paper)
    
    # find full terms in papers that have all the words, according to the index
    for term in terms:
        interesting = reduce(set.intersection, (index[word] for word in term.split()))
        for paper in interesting:
            if term in interesting.text:
                full term found
    

    (注意:我不是索引/数据检索方面的专家,可能有更好的方法来创建这样的索引,可能还有一些已经这样做的库。)

    【讨论】:

    • 或多或少这就是我实际上正在做的事情,我正在做第一次扫描
    猜你喜欢
    • 2016-10-20
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2013-11-18
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多