我正在寻找一种更好(更快)的方法来从巨大的文本文件中识别特定条目,而不是提取与该条目对应的行。该文件格式为:
>Entry1.1
#size=1688
704 1 1 1 4
979 2 2 2 0
1220 1 1 1 4
1309 1 1 1 4
1316 1 1 1 4
1372 1 1 1 4
1374 1 1 1 4
1576 1 1 1 4
>Entry2.1
#size=6251
6110 3 1.5 0 2
6129 2 2 2 2
6136 1 1 1 4
6142 3 3 3 2
6143 4 4 4 1
6150 1 1 1 4
6152 1 1 1 4
>Entry3.2
#size=1777
AND SO ON-----------
我减少了每个条目对应的行数(上图),因为它们从几百到几千不等。包含所有这些条目的文件大小范围从 100 MB 到 600 MB。我通常需要识别和提取相应行的条目数从几百到 15,000 不等。目前我正在使用 REGEX 来识别条目名称,然后提取所有相应的行直到下一个“>”符号。为了加快进程,我在 python 3.0 中使用了“多处理”包。这是简化的代码:
def OldMethod(entry):##Finds entry and extracts corresponding lines till next '>'
patbase = '(>*%s(?![^\n]+?\d).+?)(?=>|(?:\s*\Z))'###pattern for extraction of gene entry
found = re.findall(patbase % entry, denfile, re.DOTALL)
if found:
print ('Entry found in density file\n')
''Do processing of corresponding line''
return processed_result
def NewMethod(entry):##As suggested in this thread
name = entry[1]
block = den_dict[name]
if found:
''Do processing of correponding lines in Block''
def PPResults(module,alist):##Parallel processing
npool = Pool(int(nproc))
res = npool.map_async(module, alist)
results = (res.get())###results returned in form of a list
return results
main():
##Read Density file, split by '>' and make dictionary for key and corresponding lines
fh_in = open(density_file, 'r') ###HUGE TEXT FILE
denfile = fh_in2.read().split('>')[1:] ###read once use repeatedly
global den_dict
den_dict = {}
for ent in denfile:
ent_splt = ent.split('\n')
den_dict[ent_splt[0]] = ent_splt[2:-1]
##Use new approach with multiprocess
results = PPResults(NewMethod, a_list)###'a_list' holds entries for that proceesing needs to be done
for i in results:##Write Results from list to file
fh_out.write(i)
我在具有超过 500GB 和 42 个内核的服务器上运行它,但脚本仍然需要大量时间(几小时甚至一天),具体取决于要处理的大文件的大小和数量条目。在整个过程中,大部分时间都花在了定位特定条目上,因为条目的处理非常基础。
我想要实现的是尽可能减少运行时间。请建议我执行此分析的最快策略是什么。
结果:
在遵循“Janne Karila”的建议(下)并使用“NewMethod”(上)后,300 个条目的运行时间为 120 秒,其中包括 85 秒来读取巨大的密度文件并由 '>' == 35 秒分割以使用处理 300 个条目32个核心。
与 REGEX 一起使用“OldMethod”(上图)时,300 个条目的运行时间为 577 秒,其中包括 ~102 秒来读取巨大的密度文件 == 475 秒以使用 32 个内核处理 300 个条目。
读取大文件的时间从 12 秒到 102 秒波动,原因我不确定。最终,新方法至少快了 10~12 倍。目前看来是不错的改进。
谢谢
AK