我需要从几千个文件中编辑某些单词。有一个大约 50,000 字的单独参考文件需要从文件中编辑。
使用我编写的代码,这个过程将需要数周时间,我需要让它更快。
import glob, re, sys
from multiprocessing.dummy import Pool as ThreadPool
def redact_file(file):
with open(file, 'r') as myfile:
data=myfile.read()
for word in words_to_redact:
search_term = r"(?:b)"+word+r"(?:b)"
data = re.sub(search_term, '#', data, flags=re.IGNORECASE) #this seems to be the slow bit?
with open(file+'_REDACTED', 'w') as file:
file.write(data)
if __name__ == "__main__":
words_to_redact = []
with open ("words_to_redact.txt") as myfile: #about 50,000 rows in this reference file
words_to_redact=myfile.read().splitlines()
input_files = glob.glob("input_*.txt")
pool = ThreadPool(multiprocessing.cpu_count())
pool.map(redact_file, input_files)
使用多处理似乎没有帮助。
我认为性能问题来自为每个文件调用 re.sub 50,000 次。 因为这会在每次迭代时创建"data"字符串的新副本,所以我认为该过程会受到内存/缓存速度的限制。
我想我必须使用 re.sub,因为使用 regEx 是匹配单词的唯一方法。
有没有办法每次都做re.sub而无需复制,或者其他方法可以使其更快?
-
使用
re.compile()
编译模式一次,而不是每次执行搜索时 -
把你所有的话都放在一个大模式中。
然后,您的代码可能如下所示:
import re
words_to_redact = [ 'aa', 'bb', 'cc', etc...] # load 'em from file
patt = re.compile( r"(?:b)(" + '|'.join( words_to_redact ) + r")(?:b)" )
patt.sub( .. ) # you know what to do, need to call this only once (no loop)