将第一个字典中的键与第二个字典中的值进行比较

时间:2017-07-19 09:08:00

标签: python python-2.7 bioinformatics

请再次需要帮助。

我有一个包含许多信息的大数据库文件(我们称之为db.csv)。

简化数据库文件来说明:

Simplified database file to illustrate

我在我的基因序列上运行usearch61 -cluster_fast以便聚类它们 我获得了一个名为'clusters.uc'的文件。我打开它作为csv然后我创建了一个代码来创建一个字典(让我们说dict_1)将我的簇号作为键,我的gene_id(VFG ...)作为值。
以下是我将其存储在文件中的示例:dict_1

 0 ['VFG003386', 'VFG034084', 'VFG003381']  
 1 ['VFG000838', 'VFG000630', 'VFG035932', 'VFG000636']  
 2 ['VFG018349', 'VFG018485', 'VFG043567']  
 ...  
 14471 ['VFG015743', 'VFG002143']    

到目前为止一切顺利。然后使用db.csv我创建了另一个字典(dict_2),gene_id(VFG ...)是键,VF_Accession(IA ...或CVF ..或VF ...)是值,插图:dict_2

 VFG044259 IA027
 VFG044258 IA027
 VFG011941 CVF397
 VFG012016 CVF399
 ...  

我最终想要的是为每个VF_Accession提供群集组的数量,插图:

IA027 [0,5,6,8]
CVF399 [15, 1025, 1562, 1712]
...   

所以我想因为我还是编码的初学者,我需要创建一个代码,将dict_1(VFG ...)中的值与dict_2(VFG ...)中的键进行比较。如果它们匹配,则将VF_Accession作为键,将所有簇编号作为值。由于VF_Accession是键,它们不能重复我需要一个列表字典。我想我能做到这一点,因为我是为dict_1做的。但我的问题是我无法找到一种方法来比较dict_1中的值和来自dict_2的键,并将每个VF_Accession放入一个簇号。请帮帮我。

2 个答案:

答案 0 :(得分:3)

首先,让我们为您的词典添加一些更好的名称,然后dict_1dict_2,......这样可以更轻松地使用它们并记住它们包含的内容。

您首先创建了一个字典,其中簇号为keys,gene_ids(VFG ...)为值:

cluster_nr_to_gene_ids = {0: ['VFG003386', 'VFG034084', 'VFG003381', 'VFG044259'],
                          1: ['VFG000838', 'VFG000630', 'VFG035932', 'VFG000636'],
                          2: ['VFG018349', 'VFG018485', 'VFG043567', 'VFG012016'],
                          5: ['VFG011941'],
                          7949: ['VFG003386'],                              
                          14471: ['VFG015743', 'VFG002143', 'VFG012016']}

你还有另一个字典,其中gene_ids是键,VF_Accessions(IA ...或CVF ..或VF ...)是值:

gene_id_to_vf_accession = {'VFG044259': 'IA027',
                           'VFG044258': 'IA027',
                           'VFG011941': 'CVF397',
                           'VFG012016': 'CVF399',
                           'VFG000676': 'VF0142',
                           'VFG002231': 'VF0369',
                           'VFG003386': 'CVF051'}

我们想创建一个字典,其中每个VF_Accession键的值都是集群组的数量:vf_accession_to_cluster_groups

我们还注意到VF登录属于多个基因ID(例如:VF登录IA027同时具有VFG044259VFG044258基因ID。

因此我们使用defaultdict创建一个以VF Accession为键的字典,并将基因ID列表作为值

from collections import defaultdict
vf_accession_to_gene_ids = defaultdict(list)
for gene_id, vf_accession in gene_id_to_vf_accession.items():
    vf_accession_to_gene_ids[vf_accession].append(gene_id)

对于我上面发布的示例数据,vf_accession_to_gene_ids现在看起来像是:

defaultdict(<class 'list'>, {'VF0142': ['VFG000676'], 
                             'CVF051': ['VFG003386'], 
                             'IA027':  ['VFG044258', 'VFG044259'],
                             'CVF399': ['VFG012016'], 
                             'CVF397': ['VFG011941'], 
                             'VF0369': ['VFG002231']})

现在我们可以遍历每个VF Accession并查找其基因ID列表。然后,对于每个基因ID,我们遍历每个簇并查看基因ID是否存在于那里:

vf_accession_to_cluster_groups = {}
for vf_accession in vf_accession_to_gene_ids:
    gene_ids = vf_accession_to_gene_ids[vf_accession]
    cluster_group = []
    for gene_id in gene_ids:
        for cluster_nr in cluster_nr_to_gene_ids:
            if gene_id in cluster_nr_to_gene_ids[cluster_nr]:
                cluster_group.append(cluster_nr)
    vf_accession_to_cluster_groups[vf_accession] = cluster_group

现在上述样本数据的最终结果是:

{'VF0142': [], 
 'CVF051': [0, 7949], 
 'IA027':  [0], 
 'CVF399': [2, 14471], 
 'CVF397': [5], 
 'VF0369': []}

答案 1 :(得分:1)

警告:我没有做太多的Python开发,因此可能有更好的方法来做到这一点。您可以先将VFG ... gene_ids映射到它们的簇编号,然后使用它来处理第二个字典:

from collections import defaultdict
import sys
import ast

# see https://stackoverflow.com/questions/960733/python-creating-a-dictionary-of-lists
vfg_cluster_map = defaultdict(list)

# map all of the vfg... keys to their cluster numbers first
with open(sys.argv[1], 'r') as dict_1:
    for line in dict_1:
        # split the line at the first space to separate the cluster number and gene ID list
        # e.g. after splitting the line "0 ['VFG003386', 'VFG034084', 'VFG003381']",
        # cluster_group_num holds "0", and vfg_list holds "['VFG003386', 'VFG034084', 'VFG003381']"
        cluster_group_num, vfg_list = line.strip().split(' ', 1)
        cluster_group_num = int(cluster_group_num)

        # convert "['VFG...', 'VFG...']" from a string to an actual list
        vfg_list = ast.literal_eval(vfg_list)
        for vfg in vfg_list:
            vfg_cluster_map[vfg].append(cluster_group_num)

# you now have a dictionary mapping gene IDs to the clusters they
# appear in, e.g 
# {'VFG003386': [0],
#  'VFG034084': [0],
#  ...}
# you can look in that dictionary to find the cluster numbers corresponding
# to your vfg... keys in dict_2 and add them to the list for that vf_accession
vf_accession_cluster_map = defaultdict(list)
with open(sys.argv[2], 'r') as dict_2:
    for line in dict_2:
        vfg, vf_accession = line.strip().split(' ')

        # add the list of cluster numbers corresponding to this vfg... to
        # the list of cluster numbers corresponding to this vf_accession 
        vf_accession_cluster_map[vf_accession].extend(vfg_cluster_map[vfg])

for vf_accession, cluster_list in vf_accession_cluster_map.items():
    print vf_accession + ' ' + str(cluster_list)

然后保存上面的脚本并像python <script name> dict1_file dict2_file > output一样调用它(或者你可以将字符串写入文件而不是打印它们并重定向)。

编辑:在看了@ BioGeek的回答之后,我应该注意到,一次性处理这一切比创建dict_1和dict_2文件,读取它们,将行解析回数字和列表等更有意义。如果您不需要先将字典写入文件,那么您只需将其他代码添加到脚本中并直接使用字典。