获得不匹配的行号蟒蛇
您好我写了一个简单的代码在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的方式。
在此先感谢
这里是如果你的文件是有序的,不关心一些稍微更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)。
如果你的文件是有序的,你可以通过他们一步在一起,无视线,其中轨迹名称是相同的,那么当它们的不同,采取另一个步骤在您忽略文件,并重新检查。
要为比赛的更高效的搜索,你可以简单地使用set
代替list
:
Loci = set()
for line in F1:
Loci.add(line.strip())
其余部分应该工作一样,但速度更快。
更高效的是以一种锁步方式走下文件,因为它们都是排序的,但这需要更多的代码,而且可能不是必需的。
是你订购的文件吗? – 2014-10-06 04:24:31
是的,他们都订购。但是,只有File2中的一些轨迹位于File_1中,并且File1不会顺序执行。在File_1中可以从R000123跳转到R000255。 – iksaglam 2014-10-06 04:26:21
对于初学者,您可以将'Loci'变成'set'而不是'list'。这肯定会改善查找时间。 – sberry 2014-10-06 04:30:56