用 python 中的搭配词典替换文本文件中的所有搭配
Replace all collocations in a text file with a dictionary of collocations in 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 多处理代码(由于 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 将文本文件 [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 多处理代码(由于 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 秒。
我希望我没有遗漏任何东西,这将有助于加快您的代码速度。