Python 如果文件1中的A列=文件2中的A列,则替换为文件2中的B列

Python 如果文件1中的A列=文件2中的A列,则替换为文件2中的B列,python,linux,awk,Python,Linux,Awk,通常我会使用R并执行merge.by,但是这个文件似乎太大了,部门中的任何计算机都无法处理这个问题!(任何从事遗传学工作的人的补充信息)本质上,插补似乎删除了snp ID的rs编号,我只剩下染色体:位置信息。因此,我创建了一个包含我想要的所有rs编号的链接文件,并希望用文件2中的rs编号替换文件1中的Chr:Pos列 所以我在想一种编码的方法: If $3 of file 1 = $5 of file 2, replace $3 file 1 with $2 of file 2. 文件1看起来

通常我会使用R并执行merge.by,但是这个文件似乎太大了,部门中的任何计算机都无法处理这个问题!(任何从事遗传学工作的人的补充信息)本质上,插补似乎删除了snp ID的rs编号,我只剩下染色体:位置信息。因此,我创建了一个包含我想要的所有rs编号的链接文件,并希望用文件2中的rs编号替换文件1中的Chr:Pos列

所以我在想一种编码的方法:

If $3 of file 1 = $5 of file 2, replace $3 file 1 with $2 of file 2.
文件1看起来像

1111 1111 1:10583  G G
1112 1112 1:10583  G G
1113 1113 1:10583  G G
1114 1114 1:10583  G G
1115 1115 1:10583  G G
文件2看起来像

1   rs58108140  0   10583       1:10583
1   rs192319073 0   105830003   1:105830003
1   rs190151039 0   10583005    1:10583005
1   rs2809302   0   105830229   1:105830229
1   rs191085550 0   105830291   1:105830291
预期的产出将是:

1111 1111 rs58108140  G G
1112 1112 rs58108140  G G
1113 1113 rs58108140  G G
1114 1114 rs58108140  G G
1115 1115 rs58108140  G G

从文件2创建字典

with open('file2', 'r') as file2:
   replacement = {}
   for line in file2:
       splited_line = line.split()
       replacement[splited_line[4]] = splited_line[1]

with open('file1', 'r') as file1:
    with open('file1_new', 'w') as file1_new:
        for line in file1:
            splitted_line = line.split()
            splitted_line[2] = replacement.get(splitted_line[1], splitted_line[1])
            file1_new.write(' '.join(splitted_line)+'\n')

使用
awk
简单:

$ awk 'FNR==NR{a[$5]=$2;next}$3 in a{$3=a[$3]}1' file2 file1
1111 1111 rs58108140 G G
1112 1112 rs58108140 G G
1113 1113 rs58108140 G G
1114 1114 rs58108140 G G
1115 1115 rs58108140 G G

join
awk
可以做到这一点。您也可以使用
cut
而不是
awk
,但之后必须以其他方式对字段重新排序

join -1 3 -2 5 file1 file2 | awk '{print $2, $3, $7, $4, $5}'

警告:正如sudo_O所提到的,只有当文件被排序时,这才起作用-根据给定的示例,我假设它们是。如果他们没有,这不会很快。如果它们已经排序,则不需要将它们读入内存,因为这两个命令都只是在读取数据时处理数据。

文件2有多大?是否可以从第5列和第2列创建
dict
?每个文件有多大?如果文件1的第3列总是以与文件2的第5列相同的顺序出现在组中,请使用awk并在文件1中遇到新组时执行文件2的getline。现在无法提供详细信息,必须运行。sudo_o可以提供详细信息。文件1是12.3 GB,文件2是410.5 MB。我不太确定它是
文件似乎很大
没有为我出售。我的计算机似乎已经扩展到这个程度,并且它已经工作了!非常感谢你的帮助。太好了。这是因为我们只在
file2
中的一列上构建了一个数组,因此该数组将小于>410.5MB,而这在当今不会成为问题。因为我们只逐行读取
file1
,所以这不是问题。中的
a[$3]
条件应该是
$3,以避免在该条目不存在时创建该条目。@Kevin从语义上讲,它不会产生任何不同,因为空值将计算为false,但是是的,
中的$3更好。Join要求文件按顺序排序。你不想对2个大文件进行排序,然后加入它们,然后通过awk运行。也许我假设的太多了,但它们看起来确实像是在示例中排序的。
file2
未排序运行
diff file2在给定示例中,它是按最后一列排序的,我们正试图加入到最后一列中。(此处的命令应为
sort-k5 file2