使用 python 通过一组通用标识符合并两个文件



我想合并两个共享一个公共列的制表符分隔的文本文件。我有一个"标识符文件",如下所示(2 列 x 1050 行):

module 1 gene 1
module 1 gene 2
..
module x gene y

我还有一个制表符分隔的"目标"文本文件,如下所示(36 列 x 12000 行):

gene 1 sample 1 sample 2 etc
gene 2 sample 1 sample 2 etc
..
gene z sample 1 sample 2 etc

我想根据基因标识符合并两个文件,并具有标识符和目标文件中的匹配表达值和模块隶属关系。本质上是从标识符文件中获取基因,在目标文件中找到它们,并在一个文件中创建一个包含模块#,基因#和表达值的新文件。欢迎任何建议。

我想要的输出是基因 ID 选项卡模块隶属关系选项卡样本值,由选项卡分隔。

这是我想出的脚本。编写的脚本不会产生任何错误消息,但它给了我一个空文件。

expression_values = {}          
matches = []  
with open("identifiers.txt") as ids, open("target.txt") as target:  
for line in target:
expression_values = {line.split()[0]:line.split()}
for line in ids:
block_idents=line.split()
for gene in expression_values.iterkeys():    
if gene==block_idents[1]:
matches.append(block_idents[0]+block_idents[1]+expression_values)  
csvfile = "modules.csv"  
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='n')
for val in matches:
writer.writerow([val])  

谢谢!

这些代码行没有执行您期望它们执行的操作:

for line in target:
expression_values = {line.split()[0]:line.split()}
for line in ids:
block_idents=line.split()
for gene in expression_values.iterkeys():    
if gene==block_idents[1]:
matches.append(block_idents[0]+block_idents[1]+expression_values)

表达式值和block_idents将仅根据要更新它们的文件的当前行具有值。换句话说,字典和列表并没有随着更多的行被阅读而"增长"。此外,TSV文件可以使用csv模块轻松解析。

我对我建议的这个粗略解决方案做出了一些假设:

第一个文件中的"基因">
  1. 是唯一会出现的"基因" 在第二个文件中。
  2. 第一个文件中可能有重复的"基因"。

首先将第一个文件中的数据映射构造为:

import csv
from collections import defaultdict
gene_map = defaultdict(list)
with open(first_file, 'rb') as file_one:
csv_reader = csv.reader(file_one, delimiter='t')
for row in csv_reader:
gene_map[row[1]].append(row[0])

读取第二个文件并同时写入输出文件。

with open(sec_file, 'rb') as file_two, open(op_file, 'w') as out_file:
csv_reader = csv.reader(file_two, delimiter='t')
csv_writer = csv.writer(out_file, delimiter='t')
for row in csv_reader:
values = gene_map.get(row[0], [])
op_list = []
op_list.append(row[0])
op_list.extend(values)
values.extend(row[1:])
csv_writer.writerow(op_list)

现有方法存在许多问题,其中最重要的是您丢弃了除每个文件中的最后一行之外的所有数据。 每个 "for line in" 下的赋值将替换变量的内容,因此只有最后一行的最后一个赋值才会生效。

假设每个基因只出现在一个模块中,我建议你将"ids"读入字典,为每个基因保存模块:

geneMod = {}
for line in ids:
id = line.split()
geneMod[ id[0] ] = id[1] 

然后,您可以浏览目标行,对于每一行,将其拆分,获取基因 IDgene= targetsplit[0]并保存(或输出)相同的拆分字段,但插入模块值,例如:print gene, geneMod[gene], targetsplit[1:]

最新更新