如何高效地在大量XML文件中查找大量单词?

3

我有一个包含约30,000,000个化学名称的大列表和一个以XML文件形式存储在服务器上的大量文章列表(~34,000)。

我试图将每个XML作为字符串解析,查找是否提到了一个或多个化学名称。最终结果是一个制表符分隔的文本文件,其中包含文件名和出现在该文件中的化学物质列表。

目前的问题是,我使用for循环遍历所有化学成分以及嵌套在所有XMLs for循环中。for循环内部嵌套Python中的string in string操作。是否有任何方法可以通过使用比string in string更有效的操作或重新排列for循环来提高性能?

我的伪代码:

for article is articles:
         chemicals_in_article = []
         temp_article = article.lower()
         for chemical in chemicals:
               if chemical in temp_article: chemicals_in_article.append(chemical)

         #Write the results into a text file
         output_file.write(article.file_name)
         for chemical in chemicals_in_article: 
               output_file.write("\t" + chemical)
         output_file.write("\n")

               

  1. 使用xtree或libxml2解析XML文件;2) 使用xpath查询结果。快速、简单、准确。
- dawg
@dawg 可能是个好主意,避免匹配标签和属性(尽管由于领域的不同,文本可能没有重叠)。我仍然会编译一个 trie 并将其转换为 regexp,然后使用 XPath matches 进行匹配,否则速度会很慢。 - Amadan
@Amadan:同意。从你的回答中并不清楚XML将如何解析成Trie。 - dawg
@dawg 我在我的回答中澄清了。 - Amadan
2个回答

2
我不确定30M的条目是否会消耗您的内存,但基于trie的方法可能是最快的。有几个包以稍微不同的形式实现了这一点,例如FlashTexttrieregex。两者都有与您的情况完全匹配的示例。
编辑:...至少在纯文本上。根据上面的评论,如果您想避免匹配随机的标记位,请构建一个Trie然后使用XPath matches函数查找Trie派生的正则表达式找到匹配的文本节点。不幸的是,Python的主要XML库不支持matches(实际上很少有库支持XPath 2.0),因此这并不是非常可行的。
由于您只需要检测文档中任何位置的关键字出现,因此可行的解决方法是将XML转换为文本,然后使用上述方法之一。以下是一个示例:
#pip install libxml2-python3 trieregex

from trieregex import TrieRegEx as TRE
from libxml2 import parseDoc
import re


# prepare
words = ['lemon', 'lemons', 'lime', 'limes', 'pomelo', 'pomelos', 'orange', 'oranges', 'citrus', 'citruses']
tre = TRE(*words)
pattern = re.compile(fr"\b{tre.regex()}\b")
# => \b(?:l(?:emons?|imes?)|citrus(?:es)?|oranges?|pomelos?)\b


# search
xml = """
<?xml version="1.0"?>
<recipe>
  <substitute for="lemon">three limes</substitute>
  <substitute for="orange">pomelo</substitute>
</recipe>
""".strip()
doc = parseDoc(xml)
text = doc.getContent()
matches = pattern.findall(text)
print(matches)
# => ['limes', 'pomelo']
doc.freeDoc()

请注意,您只需要准备一次正则表达式;然后,您可以在多个文档上非常快速地应用它。

1

检查 正则表达式 语句。它们有时比 字符串中的字符串 更快。在尝试使用它们时,可能需要一些学习曲线。

查看this SO question and accepted answer以获取一些提示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接