我有一个看起来像这样的文件:
CHR-坐标覆盖
chr1 236968289 2
chr1 236968318 2
chr1 236968320 2
chr1 236968374 2
chr1 237005709 2
chr14 22086843 2
chr14 22086846 2
chr14 22086849 2
chr14 22086851 4
chr2 5078129 2
chr2 5341758 2
chr2 5342443 2
我想操纵它来获得:
chr-start-end-average coverage-distance
chr1 236968289 236968374 2 85
chr14 22086843 22086851 2.5 8
chr2 5078129 5078129 2 0
chr2 5341758 5342443 2 685
我想要那样: 如果chr与之前的chr 或不同,则坐标之间的差异大于1000:它会打印输出,如图所示。使用chr,起始坐标,结束坐标,平均覆盖范围以及开始和结束之间的距离。
为此,我编写了以下代码:
cov=open("coverage.txt")
oldchr="chr55" #dummy starting data
oldcoordinate=1
sumcoverage=0
startcoordinate=0
try:
while True:
line=next(cov).split("\t",2)
newchr=line[0]
newcoordinate=int(line[1]) #read informations from file
newcoverage=int(line[2].strip())
if oldchr != newchr or newcoordinate - oldcoordinate > 1000:
distance=oldcoordinate-startcoordinate
averagecoverage=sumcoverage/distance
merge=oldchr+'\t'+str(startcoordinate)+'\t'+str(oldcoordinate)+'\t'+str(averagecoverage)+'\t'+str(distance)
print merge
startcoordinate=newcoordinate
sumcoverage=0
oldchr=newchr
oldcoordinate=newcoordinate #replace old with new chr and coordinates
sumcoverage=sumcoverage+newcoverage
except(StopIteration):
print ""
我无法理解为什么它不能正常工作。 我得到的错误是获得"平均覆盖率的划分"试图按0分割,所以在很多情况下,"距离" ( distance = oldcoordinate-startcoordinate )等于0。 这不应该发生,在输入文件中永远不会出现2行具有相同坐标的情况。我无法看到错误的位置。 我希望有人可以帮助我,提前谢谢你。
答案 0 :(得分:0)
您可以使用Python的groupby
功能根据chr
列对您的条目进行分组。 csv
库还可以更轻松地处理文件:
from itertools import groupby
import csv
def display_block(block):
average_coverage = sum(x[2] for x in block) / float(len(block))
print block[0][0], "\t", block[0][1], "\t", block[-1][1], "\t", average_coverage, "\t", block[-1][1] - block[0][1]
with open('coverage.txt', 'rb') as f_coverage:
for chr, entries in groupby(csv.reader(f_coverage, delimiter='\t'), lambda x: x[0]):
entries = [(e[0], int(e[1]) , int(e[2])) for e in entries]
block = []
ientries = iter(entries)
block.append(next(ientries))
for chr, coord, coverage in ientries:
if coord - block[-1][1] > 1000:
display_block(block)
block = []
block.append([chr, coord, coverage])
if len(block):
display_block(block)
这将显示以下输出:
chr1 236968289 236968374 2.0 85
chr1 237005709 237005709 2.0 0
chr14 22086843 22086851 2.5 8
chr2 5078129 5078129 2.0 0
chr2 5341758 5342443 2.0 685
for
循环的每次迭代都会为您提供当前chr
以及该chr
的所有匹配行。该脚本遍历每一行并将coord
和coverage
转换为整数。然后它将列表作为迭代器。第一个匹配行存储在block
中,然后迭代任何剩余的行。每次距离大于1000
时,都会显示并重新启动块。然后还会显示最后的任何剩余条目。
使用Python 2.7.6进行测试