我正在从几个文件中读取,每个文件分为2个部分,首先是几千行的标题部分,后面是几千个主体。我的问题是我需要将这些文件连接到一个文件中,其中所有标题都在顶部,然后是正文。
目前我正在使用两个循环:一个用于拔出所有标头并写入它们,第二个用于写入每个文件的主体(我还包含一个tmp_count
变量来限制行数在转储到文件之前加载到内存中。)
这很慢 - 13gb文件大约需要6分钟。任何人都可以告诉我如何优化这个或者如果有更快的方法在python中执行此操作?
谢谢!
这是我的代码:
def cat_files_sam(final_file_name,work_directory_master,file_count):
final_file = open(final_file_name,"w")
if len(file_count) > 1:
file_count=sort_output_files(file_count)
# only for @ headers
for bowtie_file in file_count:
#print bowtie_file
tmp_list = []
tmp_count = 0
for line in open(os.path.join(work_directory_master,bowtie_file)):
if line.startswith("@"):
if tmp_count == 1000000:
final_file.writelines(tmp_list)
tmp_list = []
tmp_count = 0
tmp_list.append(line)
tmp_count += 1
else:
final_file.writelines(tmp_list)
break
for bowtie_file in file_count:
#print bowtie_file
tmp_list = []
tmp_count = 0
for line in open(os.path.join(work_directory_master,bowtie_file)):
if line.startswith("@"):
continue
if tmp_count == 1000000:
final_file.writelines(tmp_list)
tmp_list = []
tmp_count = 0
tmp_list.append(line)
tmp_count += 1
final_file.writelines(tmp_list)
final_file.close()
答案 0 :(得分:2)
您希望移动13Gb数据的速度有多快?这个问题是I / O绑定的,而不是Python的问题。为了加快速度,请减少I / O.这意味着你要么(a)坚持你所拥有的速度,要么(b)应该重新调整工具链的后续元素以便就地处理文件,而不是需要一个巨大的13 Gb文件。
答案 1 :(得分:2)
您可以节省第二次跳过标题所需的时间,只要您有合理数量的备用磁盘空间:以及最终文件,也打开(对于'w +')临时文件{ {1}},然后执行:
temp_file
这应该可以提高程序的性能。微调现在硬编码的import shutil
hdr_list = []
bod_list = []
dispatch = {True: (hdr_list, final_file),
False: (bod_list, temp_file)}
for bowtie_file in file_count:
with open(os.path.join(work_directory_master,bowtie_file)) as f:
for line in f:
L, fou = dispatch[line[0]=='@']
L.append(f)
if len(L) == 1000000:
fou.writelines(L)
del L[:]
# write final parts, if any
for L, fou in dispatch.items():
if L: fou.writelines(L)
temp_file.seek(0)
shutil.copyfileobj(temp_file, final_file)
,甚至完全取消列表并将每一行直接写入相应的文件(最终或临时),是您应该进行基准测试的其他选项(但如果您有无限制的话)记忆的数量,然后我希望它们无关紧要 - 但是,关于性能的直觉常常会产生误导,因此最好尝试和测量! - 。)。
答案 2 :(得分:0)
您要编写的代码中存在两个严重的低效率(这不是提供的代码):
for
块中构建大量标题行列表,而不是仅仅将其写出来。for
块中的文件标题。请参阅file.seek and file.tell