2014-10-06 76 views
1

您好我写了一个简单的代码在Python中做到以下几点:获得不匹配的行号蟒蛇

我有两个文件总结基因组数据。第一个文件有我想摆脱的位点的名字,它看起来像这样

File_1:

R000002 
R000003 
R000006 

第二个文件有我所有位点的名称和位置,看起来像这样:

File_2:

R000001 1 
R000001 2 
R000001 3 
R000002 10 
R000002 2 
R000002 3 
R000003 20 
R000003 3 
R000004 1 
R000004 20 
R000004 4 
R000005 2 
R000005 3 
R000006 10 
R000006 11 
R000006 123 

我希望做的是让所有的文件2位点的相应行号不在文件1,所以最终的结果应该是这样的:

结果:

1 
2 
3 
9 
10 
11 
12 
13 

我写了下面简单的代码,它可以完成

#!/usr/bin/env python 

import sys 

File1 = sys.argv[1] 
File2 = sys.argv[2] 

F1 = open(File1).readlines() 
F2 = open(File2).readlines() 
F3 = open(File2 + '.np', 'w') 
Loci = [] 

for line in F1: 
     Loci.append(line.strip()) 

for x, y in enumerate(F2): 
     y2 = y.strip().split() 
     if y2[0] not in Loci: 
       F3.write(str(x+1) + '\n') 

然而,当我在我的真实数据集运行作业本,其中的第一个文件有58470行第二个文件有12881010行,它似乎需要永远。我猜测的瓶颈是在代码中有贯穿整个File_2反复搜索

if y2[0] not in Loci: 

一部分,但我一直没能找到一个更快的解决方案。

任何人能帮助我,并显示处事更Python的方式。

在此先感谢

+0

是你订购的文件吗? – 2014-10-06 04:24:31

+0

是的,他们都订购。但是,只有File2中的一些轨迹位于File_1中,并且File1不会顺序执行。在File_1中可以从R000123跳转到R000255。 – iksaglam 2014-10-06 04:26:21

+0

对于初学者,您可以将'Loci'变成'set'而不是'list'。这肯定会改善查找时间。 – sberry 2014-10-06 04:30:56

回答

2

这里是如果你的文件是有序的,不关心一些稍微更Python代码。我宁愿打印所有文件并将其重定向到文件./myscript.py > outfile.txt,但您也可以传入另一个文件名并写入该文件。

#!/usr/bin/env python 
import sys 

ignore_f = sys.argv[1] 
loci_f = sys.argv[2] 

with open(ignore_f) as f: 
    ignore = set(x.strip() for x in f) 

with open(loci_f) as f: 
    for n, line in enumerate(f, start=1): 
     if line.split()[0] not in ignore: 
      print n 

在列表中搜索某事物是O(n),而对于一个集合只需要O(1)。如果订单无关紧要并且您拥有独特的商品,请在列表上使用set。虽然这不是最佳的,但它应该是O(n)而不是O(n × m),就像您的代码一样。

你还没有关闭您的文件,从读书的时候是不是什么大不了的事,但写它是什么时候。我使用上下文管理器(with),所以Python为我做。

风格的角度来看,使用描述性的变量名。并避免UpperCase名称,这些名称通常用于类别(请参阅PEP-8)。

如果你的文件是有序的,你可以通过他们一步在一起,无视线,其中轨迹名称是相同的,那么当它们的不同,采取另一个步骤在您忽略文件,并重新检查。

0

要为比赛的更高效的搜索,你可以简单地使用set代替list

Loci = set() 

for line in F1: 
    Loci.add(line.strip()) 

其余部分应该工作一样,但速度更快。

更高效的是以一种锁步方式走下文件,因为它们都是排序的,但这需要更多的代码,而且可能不是必需的。