为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

冉冉说 2021-10-12 10:42:10
我是新手,最近几个月开始在 pyhton 中编码。我有一个脚本,它需要一个蛋白质组(2850 个字符串的 800 Kb 文件)并根据一个大型数据集(作为 id:protein_string 的字典保存在代码中的 2300 万个字符串的 8Gb 文件)检查每个单独的蛋白质(protein_string)并报告 Ids所有相同的字符串(每个字符串最多可以报告 8500 个 ID)。当前脚本需要 4 小时才能运行。一般可以采取什么措施来加快进程,以及如何将我的脚本转换为多处理或多线程(不确定差异),以便进行比较的代码部分?import sysfrom Bio import AlignIOfrom Bio import SeqIOfrom Bio.Seq import Seqimport timestart_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 = 0for 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))
查看完整描述

2 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

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

让我知道这是否有帮助,以及我是否可以提供其他帮助。


查看完整回答
反对 回复 2021-10-12
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

按照 Sam Hollenbach 的建议,我可能会对您的代码进行以下 (4) 次更改。


import sys

from Bio import AlignIO

from Bio import SeqIO

from Bio.Seq import Seq

import time

start_time = time.time()

from collections import defaultdict



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" #(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 = 0

for 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))应该如何处理。


另外,不能说我已经找到了一个完整的工作程序所需的所有更改。如果您在尝试建议的更改后有任何疑问,请告诉我。


查看完整回答
反对 回复 2021-10-12
  • 2 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号