使用 dict.items() 为大型数据集优化字典查找

我是新手,最近几个月开始在 pyhton 中编码。我有一个脚本,它需要一个蛋白质组(2850 个字符串的 800 Kb 文件)并根据一个大型数据集(作为 id:protein_string 的字典保存在代码中的 2300 万个字符串的 8Gb 文件)检查每个单独的蛋白质(protein_string)并报告 Ids所有相同的字符串(每个字符串最多可以报告 8500 个 ID)。当前脚本需要 4 小时才能运行。一般可以采取什么措施来加快进程,以及如何将我的脚本转换为多处理或多线程(不确定差异),以便进行比较的代码部分?


import sys

from Bio import AlignIO

from Bio import SeqIO

from Bio.Seq import Seq

import time

start_time = time.time()


databasefile = sys.argv[1]

queryfile = sys.argv[2]


file_hits = "./" + sys.argv[2].split("_protein")[0] + "_ZeNovo_hits_v1.txt"

file_report = "./" + sys.argv[2].split("_protein")[0] + "_ZeNovo_report_v1.txt"

format = "fasta"

output_file = open(file_hits, 'w')

output_file_2 = open(file_report,'w')

sequences_dict = {}


output_file.write("{}\t{}\n".format("protein_query", "hits"))

for record in SeqIO.parse(databasefile, format):

    sequences_dict[record.description] = str(record.seq)

print("processed database in --- {:.3f} seconds ---".format(time.time() - start_time))


processed_counter = 0

for record in SeqIO.parse(queryfile, format):

    query_seq = str(record.seq)

    count = 0

    output_file.write("{}\t".format(record.description))

    for id, seq in sequences_dict.items():

        if seq == query_seq:

            count += 1

            output_file.write("{}\t".format(id))

    processed_counter += 1

    output_file.write("\n")

    print("processed protein "+str(processed_counter))

    output_file_2.write(record.description+'\t'+str(count)+'\t'+str(len(record.seq))+'\t'+str(record.seq)+'\n')

output_file.close()

output_file_2.close()

print("Done in --- {:.3f} seconds ---".format(time.time() - start_time))


冉冉说
浏览 166回答 2
2回答

万千封印

初步在我看来,它可能更有意义,而不是将您的 dict 存储为{ id : seq },将其存储为{ seq : [id_list] }. 由于听起来每个序列有很多重复,这将节省访问特定序列的所有 ID 的时间。您可以在读取数据时使用defaultdict带有默认值的 a 作为空列表来执行此操作,并且当您读取 ID 和序列时,您可以使用 将其添加到 dict 中sequences_dict[record.seq].append(record.description)。让我知道这是否有帮助,以及我是否可以提供其他帮助。

料青山看我应如是

按照 Sam Hollenbach 的建议,我可能会对您的代码进行以下 (4) 次更改。import sysfrom Bio import AlignIOfrom Bio import SeqIOfrom Bio.Seq import Seqimport timestart_time = time.time()from collections import defaultdictdatabasefile = sys.argv[1]queryfile = sys.argv[2]file_hits = "./" + sys.argv[2].split("_protein")[0] + "_ZeNovo_hits_v1.txt"file_report = "./" + sys.argv[2].split("_protein")[0] + "_ZeNovo_report_v1.txt"_format = "fasta" #(change 1)output_file = open(file_hits, 'w')output_file_2 = open(file_report,'w')sequences_dict = defaultdict(list)output_file.write("{}\t{}\n".format("protein_query", "hits"))for record in SeqIO.parse(databasefile, _format):    sequences_dict[record.seq].append(record.description) #(change 2)    #sequences_dict[record.description] = str(record.seq)print("processed database in --- {:.3f} seconds ---".format(time.time() - start_time))processed_counter = 0for record in SeqIO.parse(queryfile, _format):    query_seq = record.seq #(change 3)    count = 0    output_file.write("{}\t".format(record.description))    if query_seq in sequences_dict: #(change 4)        count = len(sequences_dict[query_seq])        output_file.write('\t'.join(sequences_dict[query_seq]) + "\n")    processed_counter += 1    print("processed protein", processed_counter)    output_file_2.write(record.description+'\t'+str(count)+                        '\t'+str(len(record.seq))+'\t'+str(record.seq)+'\n')output_file.close()output_file_2.close()print("Done in --- {:.3f} seconds ---".format(time.time() - start_time))更改 #1: - 将格式变量的名称更改为 _format(以避免与 Python 术语“格式”发生冲突,并在使用该名称的代码中进行更改。更改 #2:使用record.seq作为字典的键并将 附加record.description到列表中(作为值)更改 #3:无需强制record.seq转换str- 它已经是一个字符串。更改 #4:这 3 行将比在原始代码中迭代字典更快地定位任何匹配的记录。我不确定output_file.write("{}\t".format(record.description))应该如何处理。另外,不能说我已经找到了一个完整的工作程序所需的所有更改。如果您在尝试建议的更改后有任何疑问,请告诉我。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python