【问题标题】:Efficiently searching a body of text for a large number of keywords (1000's)有效地搜索大量关键字(1000 个)的正文
【发布时间】:2021-02-23 22:49:15
【问题描述】:

我正在从事一个项目,我需要搜索中短文本(一个会话最多 100 个)以查找 1000 个不同关键字(股票市场符号)的存在。我正在使用 Python。

现在,我知道如果我用一个简单的 For 循环来解决这个问题,这可能需要很长时间。

最有效的方法是什么?是否有一个特定的 python 库在这里最有利?

编辑:有关我的用例的更多详细信息:

  • 我正在搜索的正文是不同长度的 Reddit 帖子(假设上限为 2000 个字符)。
  • 我将在每个会话中搜索大约 100 - 200 个不同的帖子。
  • 我需要检查每个帖子中是否存在 1 个或多个股票代码。有 1000 种股票代码可供搜索,它们的表示格式各不相同,因此我需要检查部分匹配项(即 GOOG 和 $GOOG 在正文中都匹配)。
  • 我需要列出在给定帖子中找到的符号。

我希望这能提供一些澄清。

谢谢。

根据答案发布解决方案:

这是我最终用来将股票代码编译成正则表达式的基本代码。请注意,符号存储在名为“self.symbols”的 Python 字典中 - 其中每个键都是一个交换,并包含一个符号列表作为它的值。

#Return the dict of stock symbols
def compileSymbols(self):

    #Will hold compiled symbols
    dict = {}

    #For each exchange in dict, join list of symbols and convert to compiled regex
    for key in self.symbols.keys():
        joinedStr = "|".join(self.symbols[key])
        dict[key] = re.compile(r"{0}".format(joinedStr))
    
    #Save compiled symbols
    self.symbols = dict

...然后我使用下面的代码循环浏览帖子文本并搜索符号 - 将结果转换为集合并返回列表以删除重复项:

#Check posts for matching symbols
def searchPostsForSymbols(self, posts, symbols):

    for post in posts:
    
        #Used to store matching symbols
        matches = []
    
        for exchng in symbols.keys():
            result = symbols[exchng].findall(post, re.M)
            result = list(set(result))
            if len(result) > 0:
                matches.append((exchng, result))

花费数秒时间搜索 1000 个符号 - 性能出奇的好。谢谢马洛的回答!

【问题讨论】:

  • 你试过用正则表达式是否更快?这取决于比赛时您想做什么?请详细说明您的目标和预期结果。
  • @Malo 我已经用其他信息更新了我的问题。基本上,我需要能够检测最多 2000 个字符正文中的关键字/符号,并列出匹配项。
  • 这是一个有趣的问题。 现在,我知道如果我用一个简单的 For 循环来解决这个问题,这可能需要很长时间。 -- 这表明你没有尝试解决这个问题。如果你能给我们一些咬牙切齿的东西,这对我们和后代来说真的是有益的。如果您不确定从哪里开始,请查看有关在 stackoverflow 上提出好问题的指南。如前所述,作为起点,请尝试使用正则表达式(或 regex)。
  • 您可能对我发布的与此类似的答案感兴趣:stackoverflow.com/a/66325181/2359945 请注意,解决方案每次匹配使用 1 个迭代器,并且每个迭代器遍历整个字符串,因此您可能需要做额外的工作或者可能不在乎。

标签: python arrays search set


【解决方案1】:

这里有一个使用正则表达式可以获得的示例。如果对您的情况有用,请尝试并计时:

import re

text = """
This is text with
ThiGOOGs is text with
This is tMICRext with
This is text with
This isGOOG text with
This is text with
"""

c = re.compile(r"STOCK|GOOG|MICR")
r = c.findall(text, re.M)
print(r)

输出是:

['GOOG', 'MICR', 'GOOG']

【讨论】:

  • 谢谢!这实际上具有令人难以置信的出色表现,让我感到惊讶......我已经根据您的回答用我的解决方案更新了这个问题。
  • 很高兴知道它很有用。如果您设法使用 re.compile(...) 语句,并且只在循环外使用一次(并始终保持相同的符号列表)。如果你编译一次,你甚至可以加快这个过程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2011-10-03
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多