比较从第一字典值从第二词典

问题描述:

键请我又需要一些帮助。比较从第一字典值从第二词典

我有一个大的数据库文件(姑且称之为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值放入一个簇号。请帮帮我。

+0

我不对生物有很多了解 - 同一个gene_id(VFG)能够出现在多个集群中吗? –

+0

是的,其中有些是不幸的。也许有类似的IA027 [0 | 12,5,6,8]或IA027 [0(12),5,6,8] –

首先,让我们给你的字典一些更好的名字,然后dict_1,dict_2,...使它更容易与它们一起工作,并记住它们包含的内容。

你先创建一个具有群集号作为键和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加入属于多基因标识(例如:在VF加入IA027既有VFG044259VFG044258基因标识

因此我们使用defaultdict,以与VF加入字典作为。键和值

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': []} 
+0

我真的真的很感谢您的帮助,但是如果您可以帮助我更多,还是会有一些问题:在cluster_nr_to_gene_ids中,同一个gene_id可以有多个簇号。插图:0 ['VFG003386'] 7949 ['VFG003386']所以vf_accession应该包含这两个群集组。 CVF051 ['0,7949']但它只给我一个:CVF051 [0] –

+0

@rookiemax,我的代码在基因ID处于多个群集时起作用,请参阅我用您提供的示例更新的示例数据。看到你做错了什么,或者你需要提供一个更完整的数据集来查看事情出错的地方。 – BioGeek

+1

你是对的我做错了什么,我的坏。在我删除了一行代码后,它非常完美:D我真的非常棒,谢谢你的帮助:D真的很坦然:D –

警告:我没有做很多Python开发,所以有可能是一个更好的方式来做到这一点。您可以gene_ids首先映射你的VFG ......他们的簇号,然后用它来处理第二词典:

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文件,阅读它们,解析线回数字和列表,等等。如果你不需要字典先写一个文件,那么你可以添加其他的代码脚本,并直接使用的字典。

+1

我很感谢你的帮助:D –

+0

我实际上使用你的一些代码来解决我的问题。另外我学到了python编码的新东西,所以再次感谢:D –

+0

很高兴听到它有帮助! –