0

我编写了一个代码以将文本文件作为输入并仅打印重复多次的变体。我所说的变体是指文本文件中的 chr 位置。

输入文件如下所示:

chr1 1048989 1048989 AG intronic C1orf159 0.16 rs4970406
chr1 1049083 1049083 CA intronic C1orf159 0.13 rs4970407
chr1 1049083 1049083 CA intronic C1orf159 0.13 rs4970407
chr1 1113121 1113121 GA intronic TTLL10 0.13 rs12092254

如您所见,第 2 行和第 3 行重复。我只是取前 3 列,看看它们是否相同。在这里,chr1 1049083 1049383 在 row2 和 row3 中重复。所以我打印出来说有一个重复,它的位置。

我已经写了下面的代码。虽然它正在做我想要的,但它很慢。在一个有 700,000 行的文件上运行大约需要 5 分钟。我想知道是否有办法加快速度。

谢谢!

#!/usr/bin/env python
""" takes in a input file and 
    prints out only the variants that occur more than once """

import shlex
import collections

rows = open('variants.txt', 'r').read().split("\n")
# removing the header and storing it in a new variable
header = rows.pop()
indices = []

for row in rows:
    var = shlex.split(row)
    indices.append("_".join(var[0:3]))

dup_list = []
ind_tuple = collections.Counter(indices).items()

for x, y in ind_tuple:
    if y>1:
        dup_list.append(x)

print dup_list    
print len(dup_list)

注意:在这种情况下,整个 row2 是 row3 的副本。但这并不一定总是如此。我正在寻找重复的 chr 位置(前三列)。

编辑:根据 damienfrancois 的建议编辑了代码。以下是我的新代码:

f = open('variants.txt', 'r')
indices = {}
for line in f:
    row = line.rstrip()   
    var = shlex.split(row)
    index = "_".join(var[0:3])
    if indices.has_key(index):
        indices[index] = indices[index] + 1
    else:
        indices[index] = 1

dup_pos = 0        
for key, value in indices.items():
    if value > 1:
        dup_pos = dup_pos + 1

print dup_pos

我用了,时间来看看这两个代码需要多长时间。

我的原始代码:

time run remove_dup.py 
14428 
CPU times: user 181.75 s, sys: 2.46 s,total: 184.20 s 
Wall time: 209.31 s

修改后的代码:

time run remove_dup2.py 
14428
CPU times: user 177.99 s, sys: 2.17 s, total: 180.16 s
Wall time: 222.76 s

我没有看到任何显着的改善。

4

2 回答 2

1

一些建议:

  • 不要一次读取整个文件;逐行读取并即时处理;您将节省内存操作

  • 让 index 成为默认字典并增加键 "_".join(var[0:3]) 的值;这节省了昂贵的(在这里猜测,应该使用分析器) collections.Counter(indices).items() 步骤

  • 尝试pypypython 编译器

  • 将您的数据拆分为与计算机具有的内核一样多的子集,将程序并行应用于每个子集,然后合并结果

高温高压

于 2013-10-11T19:48:33.427 回答
0

一个大的时间槽可能是if..has_key()代码的一部分。以我的经验,try-except 要快得多......

f = open('variants.txt', 'r')
indices = {}
for line in f: 
    var = line.split()
    index = "_".join(var[0:3])
    try:
        indices[index] += 1
    except KeyError:
        indices[index] = 1
f.close()
dup_pos = 0        
for key, value in indices.items():
    if value > 1:
        dup_pos = dup_pos + 1

print dup_pos

另一种选择是将四行替换为try except

indices[index] = 1 + indices.get(index,0)

这种方法只告诉有多少行重复,而不是重复多少次。(所以如果一条线被骗了 3 倍,那么它会说 1...)

如果您只是尝试计算重复项而不是删除或记下它们,您可以随时计算文件的行数,并将其与indices字典的长度进行比较,区别在于重复行数(而不是循环并重新计数)。这可能会节省一点时间,但会给出不同的答案:

#!/usr/bin/env python

f = open('variants.txt', 'r')
indices = {}
total_len=0
for line in f: 
    total_len +=1
    var = line.split()
    index = "_".join(var[0:3])
    indices[index] = 1 + indices.get(index,0)
f.close()  
print "Number of duplicated lines:", total_len - len(indices.keys())

我很想知道您对包含has_key()测试的代码的基准是什么...

于 2013-10-15T00:33:09.227 回答