我需要速度。比较两个非常大的字典:键是索引原始 pandas 索引存储为元组,值是字符串列表

I need speed. Comparing two very large dictionaries: key are indexes original pandas index stored as tuples, values are lists of strings

首先感谢您对我阅读和使用过的其他人提出的上千个问题的解答。但现在我需要 post 我自己的问题。在 4000 行运行良好的代码中,以下 6 行过去需要数周,现在需要几天,但我仍然需要它 运行 更快。我的一段特别慢的代码:

    for i in PepCombDict.items():
        for x in PepSeqDictFull_NoneUnique_NRP.items():
            if x[0] == i[0][0] or x[0] == i[0][1]:
                continue
            elif(set(x[1]).issubset(set(i[1]))):
                subsumablelist.append([i[0][0],i[0][1],x[0]]) 

PepCombDict 是一个字典,第一个条目如下: 键是一对值:(0, 1) 值为列表:

['TVMENFVAFVDK', 'KVPQVSTPTLVEVSR', 'DTHKSEIAHR', 'YICDNQDTISSK', 'KQTALVELLK', 'FKDLGEEHFK', 'EYEATLEECCAK', 'AEFVEVTK', 'LVNELTEFAK', 'LVTDLTK', 'LGEYGFQNALIVR', 'LSQKFPK', 'HLVDEPQNLIK', 'YLYEIAR', 'SIVHPSYNSNTLNNDIMLIK', 'SAYPGQITSNMFCAGYLEGGK', 'LKSAASLNSR', 'SAASLNSR', 'SGIQVR', 'NKPGVYTK', 'LGEDNINVVEGNEQFISASK', 'SSGTSYPDVLK', 'APILSDSSCKSAYPGQITSNMFCAGYLEGGK', 'SIVHPSYNSNTLNNDIMLIKLK']

类似地,PepSeqDictFull_NoneUnique_NRP也是一个字典,首条目如下: 键是单个值:9 值为:列表

['VTMQNLNDR', 'QSVEADINGLR', 'QSVEADINGLRR', 'LAADDFR', 'DYSKYYK', 'SKELTTEIDNNIEQISSYK', 'KDAEAWFNEK', 'ISSSKGSLGGGFSSGGFSGGSFSR', .....

这个代码块的objective是找出所有在PepSeqDictFull_NoneUnique_NRP中找到的字符串序列列表是在PepCombDict中找到的字符串序列的子集的所有情况;找到后,将键(索引)保存为三个数字的列表(两个键的组合)。

如果有人知道如何使它运行得更快,我将不胜感激。我完全愿意改变任何部分的格式。我从这次大流行中学到了 python,并希望坚持 python。 PepSeqDictFull_NoneUnique_NRP 总是更小。 PepCombDict 大小范围为 2,000,000 到 100,000,000。

if x[0] == i[0][0] or x[0] == i[0][1]: continue 只是为了防止条目被发现是其自身的子集。

最佳,

汤姆

combs = {
    (0, 1): ['TVMENFVAFVDK', 'KVPQVSTPTLVEVSR', 'DTHKSEIAHR', 'YICDNQDTISSK', 'KQTALVELLK', 'FKDLGEEHFK', 'EYEATLEECCAK', 'AEFVEVTK', 'LVNELTEFAK', 'LVTDLTK', 'LGEYGFQNALIVR', 'LSQKFPK', 'HLVDEPQNLIK', 'YLYEIAR', 'SIVHPSYNSNTLNNDIMLIK', 'SAYPGQITSNMFCAGYLEGGK', 'LKSAASLNSR', 'SAASLNSR', 'SGIQVR', 'NKPGVYTK', 'LGEDNINVVEGNEQFISASK', 'SSGTSYPDVLK', 'APILSDSSCKSAYPGQITSNMFCAGYLEGGK', 'SIVHPSYNSNTLNNDIMLIKLK']
}

seqs = {
    9: ['VTMQNLNDR', 'QSVEADINGLR', 'QSVEADINGLRR', 'LAADDFR', 'DYSKYYK', 'SKELTTEIDNNIEQISSYK', 'KDAEAWFNEK', 'ISSSKGSLGGGFSSGGFSGGSFSR']
}

,你可以在循环外创建集合:

combs = {k: set(v) for k, v in combs.items()}
seqs = {k: set(v) for k, v in seqs.items()}

您还可以在构建时进行列表推导 subsumablelist:

subsumablelist = [
    [comb_ids[0], comb_ids[1], seq_id]
    for comb_ids, comb in combs.items()
    for seq_id, seq in seqs.items()
    if (seq_id not in comb_ids) and all(subseq in comb for subseq in seq)
]

使用 timeit,从您的代码 (4.97s) 到建议的代码 (3.03s) 的时间改进为 39%。


使用 seq.issubset(comb) 而不是 all(subseq in comb for subseq in seq) (2.79s) 将时间改进增加到 43%。