附加多个文件并使用词典删除重复项

jul*_*les 2 python merge dictionary duplicate-removal

所以我有一些文件看起来像:

snpID  Gene
rs1  ABC1
rs2  ABC1
rs3  ABC25
rs4  PT4
rs5  MTND24
Run Code Online (Sandbox Code Playgroud)

在不同的文件中,将存在其他snpID和基因对,但是对于给定的snpID可能存在重复,但相关联的"基因"可能不同.例如:

snpID  Gene
rs100  URX1
rs95  KL4
rs1  ABC1
rs2  ABC1-MHT5
rs3  ABC25
rs4  PT4-FIL42
Run Code Online (Sandbox Code Playgroud)

我想要做的是附加文件的所有内容,如果它们具有相同的snpID和Gene对,则删除重复项.然而,如果snpID的相应基因不同,则它必须进入同一行.对于上面的示例,它应该如下所示:

snpID  Gene
rs1  ABC1
rs2  ABC1, ABC1-MHT5
rs3  ABC25
rs4  PT4, PT4-FIL42
rs5  MTND2
rs100  URX1
rs95  KL4
Run Code Online (Sandbox Code Playgroud)

我以为我可以通过创建词典来实现这一目标.

import glob
file_list = glob.glob('annotations.*')
dict_snps_genes = {}
for filename in file_list:
    with open(filename) as fileA:
        for line in fileA:
            col0 = line.split()[0]
            col1 = line.split()[1]
            dict_snps_genes[col0] = col1 

unique_dict_snps = {}
for key,value in dict_snps_genes:
    if key not in unique_dict_snps.keys():
        unique_dict_snps_genes[key] = value
Run Code Online (Sandbox Code Playgroud)

我在进一步移动之前测试了这个,这给我一个错误,如:

ValueError: too many values to unpack
Run Code Online (Sandbox Code Playgroud)

PS:每个文件大约有8000个snpId-Gene对,并且有超过5个文件

关于如何通过这个的想法!!

Mar*_*ers 6

您正在循环键,但尝试将它们分配给键和值变量:

for key,value in dict_snps_genes:
Run Code Online (Sandbox Code Playgroud)

改变它循环.items():

for key,value in dict_snps_genes.items():
Run Code Online (Sandbox Code Playgroud)

或者更好的是,如果在Python 2.x上,使用`.iteritems():

for key,value in dict_snps_genes.iteritems():
Run Code Online (Sandbox Code Playgroud)

请注意,您阅读文件的方式,您只存储任何给定snpID的最后读取基因; 如果找到该ID的另一个条目,则覆盖前一个.

就个人而言,我会使用collections.defaultdict()一个set默认的:

import glob
import collections

file_list = glob.glob('annotations.*')
snps_genes = collections.defaultdict(set)
for filename in file_list:
    with open(filename) as fileA:
        for line in fileA:
            snpid, gene = line.strip().split(None, 1)
            snps_genes[snpid].add(gene)
Run Code Online (Sandbox Code Playgroud)

现在,价值观snps_genes是基因组,每个基因都是独一无二的.请注意,我在whitespace(.split(None, 1))上将您的行拆分为2个,这样如果基因值中有任何空格,它将被存储为:

>>> 'id gene with whitespace'.split(None, 1)
['id', 'gene with whitespace']
Run Code Online (Sandbox Code Playgroud)

通过使用`snpid,gene'作为左手赋值表达式Python获取分割的结果并将每个片段分配给一个单独的变量; 这里有一个方便的技巧来保存一行代码.

要将其输出到新文件,只需遍历生成的snps_genes结构.这是一个排序一切:

for id in sorted(snps_genes):
    print id, ', '.join(sorted(snps_genes[id]))
Run Code Online (Sandbox Code Playgroud)