【问题标题】:Python: words replacing in huge textPython:替换大文本中的单词
【发布时间】:2011-09-06 16:26:31
【问题描述】:

我有一个巨大的文本和一个大约 10K 的单词列表。 在 Python 中用其他单词替换所有这些单词的最快方法是什么?

编辑: 文本大小 >1Gb,文本是人工编写的,并且“高度标记化”(任何字母数字字符和任何其他单个符号都被拆分为新标记)

词数>10K,文本中每个词频为1 替换词在所有替换中都是相同的。 Python 2.5-2.7

【问题讨论】:

  • 您的意思是列表中有 10000 个单词还是您的文本大小为 10000 个字节?单词列表和文本哪个更大?
  • 文字大小>1Gb,字数>10K。
  • 什么版本的python?每个搜索词是否对应一个替换词,或者您是否将所有搜索词替换为相同的替换词?一开始的文本有多“常规”?空格分隔、标点符号、变量?
  • 文本是人工编写的,并且“高度标记化”(任何字母数字字符和任何其他单个符号都被拆分为新标记);文本中的每个词频为 1,替换词在所有替换中都相同。 Python 2.5-2.7

标签: python text replace


【解决方案1】:

如果输入格式和搜索/替换配对信息接近开始,则需要完善这个答案,但这将是我最初的尝试(假设输入数据中存在某种形式的规律性,空格分隔下面是我的示例代码)。

replacements = {
  's1': 'r1',
  's2': 'r2'
  ...
}

with open('input.txt') as fhi, open('output.txt', 'w') as fho:
  for line in fhi:
    words = line.split(' ')

    fho.write(' '.join(map(lambda w: replacements.get(w, w), words))

    # Or as a list comprehension from the comments.
    fho.write(' '.join([replacements.get(w, w) for w in words]))

这里的想法是我们将数据从输入文件重新定位到输出文件中。对于每一行的每个单词,我们检查它是否在我们的替换字典中。如果是,我们将检索新值,否则通过 dict.get(key[, default]) 方法返回未更改的单词。这可能并不理想,不处理标点符号,可能会在输入文件没有分成几行时遇到问题等,但可能是一种入门方式。

【讨论】:

  • 注意,我利用了支持多个文件的 with 的 2.7 语法。如果您使用的是 2.5 或 2.6,则必须嵌套 with 语句才能处理两个文件(或创建一个处理多个文件的自定义上下文管理器)。
  • 谢谢,您的解决方案 ' '.join(map(lambda w: replacements.get(w, w), words)) 在我的情况下非常快(加载内存中的所有数据+“非常标记化”文本)。
  • @Alex - 很高兴为您提供帮助。如果您找到了一种可行的方法,请务必标记答案,这样人们就不会继续尝试为您解决问题。 :)
  • 这在性能上与列表理解相比如何? out.write( ' '.join( [ replacements.get( w, w ) for w in line.split() ] )
  • @dusktreader - 列表理解实际上可能最终会更快一点,这绝对是可能的。我将更新答案以将其作为替代。谢谢!
【解决方案2】:

我建议一种简单的方法,一次替换一行:

pattern1 = 'foo'
pattern2 = 'bar'

with open('input.txt') as input, open('output.txt', 'w') as output:
    for line in input:
        output.write(line.replace(pattern1, pattern2))

【讨论】:

    【解决方案3】:

    哇!这一点都不是微不足道的。这是一个想法:

    第 1 步:将文本量化为单词、符号等。 函数 quantize 接受文本作为参数, 输出是单词和符号的列表。 def 量化(文本:str)-> 列表: ... 可以从给定列表构造 a 的逆函数: def dequantize(lst: list) -> str: …… 步骤 2:建立一个量化列表的字典,以便 d_rep[字] = 字 然后,使用替换词列表来转换这个字典,如下所示: d_rep[word] = 替换 第 3 步:遍历量化列表中的每个单词,并将其替换为来自 d_rep 字典。它可能是原始词或替代词。 第 4 步:对列表进行反量化并恢复文本。

    如果您有大文本和大量搜索/替换词,这应该是最佳选择。祝你好运!询问,如果您有任何实施问题。

    更新: 使用单个替换词,更容易,从“10K”词表创建一个集合,然后对于量化列表中的每个词,如果集合中的词,则在该列表中替换它。

    在伪 python 代码中:

    qlist = quantize(text)
    
    for i in range(0, len(qlist)):
        word = qlist[i]
        if word in wordlist_set:
            qlist[i] = 'replacement'
    
    text = dequantize(qlist)
    

    【讨论】:

      【解决方案4】:

      如果你有足够的内存,最快的方法可能是将文本读取为字符串并使用正则表达式搜索并执行替换:

      def replace(matched):
          # Matched.group(0) is the word that was found
          # Return the replacement
          return "REPLACEMENT"
      
      # The \b ensure that only whole words are matched.
      text = re.sub(r"\b(%s)\b" % "|".join(words), replace, text)
      

      如果你没有记忆,试着分块做,也许:

      # Read a chunk and a line to ensure that you're not truncating a word.
      chunk = text_file.read(1024 ** 2) + text_file.readline()
      

      【讨论】:

      • 我收到一个错误:OverflowError: 正则表达式代码大小限制超出
      • PyPI 上有一个正则表达式实现,应该能够处理它。
      猜你喜欢
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多