python - 用python中的搭配字典替换文本文件中的所有搭配
问题描述
我正在尝试使用 python 将文本文件 [corpus.txt] 中的子字符串替换为其他一些子字符串 [collocation|ngram]。我在包含以下内容的文件 sub.txt 中有可能的子字符串列表:
dogs chase
birds eat
chase birds
chase cat
chase birds .
和一个 corpus.txt 包含一些文本如下:
dogs chase cats around
dogs bark
cats meow
dogs chase birds
cats chase birds , birds eat grains
dogs chase the cats
the birds chirp
具有所需的输出
<bop> dogs chase <eop> cats around
dogs bark
cats meow
<bop> dogs chase <eop> birds
cats <bop> chase birds <eop> , <bop> birds eat <eop> grains
<bop> dogs chase <eop> the cats
the birds chirp
还有我的带有多处理的python代码(由于 and 的大小而使用了多corpus
处理sub
)
import sys
import string
import time
from multiprocessing import Pool
import re
import itertools
flatten = itertools.chain.from_iterable
#corpus_dir = sys.argv[1]
#ngram_dir = sys.argv[2]
#f = open(corpus_dir) # Open file on read mode
#corpus = f.read().split("\n") # Create a list containing all lines
#f.close() # Close file
#f2 = open(ngram_dir) # Open file on read mode
#sub = f2.read().split("\n") # Create a list containing all lines
#f2.close() # Close file
sub = ['dogs chase', 'birds eat', 'chase birds', 'chase cat', 'chase birds .']
corpus = [' dogs chase cats around ', ' dogs bark ', ' cats meow ', ' dogs chase birds ', ' cats chase birds , birds eat grains ', ' dogs chase the cats ', ' the birds chirp ']
print("The corpus has ", len(corpus))
sbsx = { " "+ng+" " : " <bop> "+ng+" <eop> " for ng in sub }
def multiple_replace(string, rep_dict):
pattern = re.compile("|".join([re.escape(k) for k in sorted(rep_dict,key=len,reverse=True)]), flags=re.DOTALL)
print("replaced = ")
return pattern.sub(lambda x: rep_dict[x.group(0)], string)
def f(a_list):
out = [multiple_replace(sent, sbsx) for sent in a_list]
'''out = []
for sent in a_list:
c = multiple_replace(sent, sbsx)
out.append(c)
#print(c)
time.sleep(0.01)
'''
return out
def f_amp(a_list):
#chunks = [a_list[i::5] for i in range(5)]
chunks = [a_list[x:x+5] for x in range(0, len(a_list), 5)]
print(len(chunks))
pool = Pool(processes=10)
result = pool.map_async(f, chunks)
while not result.ready():
print("Running...")
time.sleep(0.5)
return list(flatten(result.get()))
final_anot = f_amp(corpus)
print(final_anot)
我添加了已经初始化corpus
的sub
变量(在上面的代码片段中)来展示代码是如何工作的。在实际设置中,两者都corpus.txt
包含sub.txt
数百万行(分别为 200M+ 和 4M+)。我需要一个可以有效完成任务的代码,我已经尝试过Multiprocessing
,pool
但需要数周才能完成。还有其他有效和快速的方法来完成这项任务吗?
解决方案
您正在为每个句子重新编译您的模式。这需要相当多的时间。相反,您可以在全局范围内编译您的模式一次:
sbsx = { " "+ng+" " : " <bop> "+ng+" <eop> " for ng in sub }
pattern = re.compile("|".join([re.escape(k) for k in sorted(sbsx,key=len,reverse=True)]), flags=re.DOTALL)
def multiple_replace(string):
print("replaced = ")
return pattern.sub(lambda x: sbsx[x.group(0)], string)
我用你的例句测试了 100 万次,我从 52 秒到只有 13 秒。
我希望我没有错过任何东西,这将有助于加快您的代码速度。
推荐阅读
- python - 有多少国家组织了不止一届奥运会?使用 python 熊猫
- python - 使用 psycopg2 插入大量数据无法正常工作
- c++ - 有没有办法通过在 C++ 中输入一些东西来停止正在进行的循环?
- swift - 在多个图像视图上使用点击手势识别器
- python - 为什么 df.isnull().sum() 以它的方式工作?
- javascript - 如何使用网络加密导入加密的 RSA 私钥
- r - 在单词之间粘贴输入名称以使用 write.table 保存
- r - 是否有更快的重写来处理缺少的 XML 属性?
- javascript - 处理具有数据限制限制的重复 API 查询的最佳方法
- react-native - React Native Flatlist - 仅在可见时运行功能