生信编程2.hg38基因组序列的一些探究

有一些五六年前的学生们都成长为了各个生物信息学相关公司的小领导,而且他们都有了自己的公众号,知乎号,也算是一番人物。最近他们跟我反馈面试找不到或者说很难直接考核筛选到认真干活的生信工程师,挺有意思的。让我想起来了早在生信技能树论坛创立之初我为了引流,而规划的200个生信工程师面试题。值得继续分享:

200个生信工程师面试考题

统计hg38基因组中的GC含量

统计N和GC含量==> 分别统计ATGCN的数量,然后使用(N数量/总数,G数量+C数量/总数)

  • 首先要构建数据结构,也就是说用这种数据结构来统计碱基数量 python中的字典

{
  'chr1':{
          'A':n,
          'T':n,
          'C':n,
          'G':n,
          'N':n
         },
  'chr2':{
          'A':n,
          'T':n,
          'C':n,
          'G':n,
          'N':n
         },
}

  • 初级脚本

hg38 = open('test.fa','r')

sum_atgc = {}
for line in hg38:
    if line.startswith('>'):
       chr_id = line[1:]
       sum_atgc[chr_id] = {}
       sum_atgc[chr_id]['A'] = 0
       sum_atgc[chr_id]['T'] = 0
       sum_atgc[chr_id]['G'] = 0
       sum_atgc[chr_id]['C'] = 0
       sum_atgc[chr_id]['N'] = 0
    else:
       line = line.upper()
       sum_atgc[chr_id]['A'] += line.count('A')
       sum_atgc[chr_id]['T'] += line.count('T')
       sum_atgc[chr_id]['G'] += line.count('G')
       sum_atgc[chr_id]['C'] += line.count('C')
       sum_atgc[chr_id]['N'] += line.count('N')

for chr_id,atgc_count in sum_atgc.items():
     print(chr_id)
     GC = int(atgc_count['G']) + int(atgc_count['C'])
     total = sum(atgc_count.values())
     print("A : %s" % (atgc_count['A']))
     print( "T : %s" % (atgc_count['T']))
     print( "G : %s" % (atgc_count['G']))
     print( "C : %s" % (atgc_count['C']))
     print( "N : %s" % (atgc_count['N']))
     print( "total : %s" % (sum(atgc_count.values())))
     print("CG_per : %s" % (GC/total))
     print("N_per : %s" % (int(atgc_count['N'])/total))

虽然逻辑上符合,而且也能够计算出目的的结果,但是重复代码太多,需要进行优化 ==注意== 由于基因组中可能同时存在大小写不同的碱基,所以在进行统计的时候需要统一大小写line.upper()

  • 减少代码重复问题

#!/usr/bin/python
import sys

args = sys.argv
hg38 = open(args[1],'r')

bases = ['A','T','G','C','N']

sum_atgc = {}
for line in hg38:
    if line.startswith('>'):
       chr_id = line[1:]
       sum_atgc[chr_id] = {}
       for base in bases:
           sum_atgc[chr_id][base] = 0
    else:
       line = line.upper()
       for base in bases:
           sum_atgc[chr_id][base] += line.count(base)

for chr_id,atgc_count in sum_atgc.items():
     print(chr_id)
     GC = int(atgc_count['G']) + int(atgc_count['C'])
     total = sum(atgc_count.values())
     for base in bases:
         print("%s : %s" % (base, atgc_count[base]))
     print( "total : %s" % (total))
     print("CG_per : %s" % (GC/total))
     print("N_per : %s" % (int(atgc_count['N'])/total))

==注意== 将需要进行处理的碱基放到一个列表中,然后对列表进行循环,这样就能避免重复写相同的代码

从1开始写python

  • 0.5 开始课程
  • 1 基础语法
  • 2 编程技巧(打开文件,参数处理等)
  • 3 效率(程序的运行时间)

提高效率

#!/usr/bin/python
import sys
import time
import re

start = time.process_time()
args = sys.argv

sum_atgc = {}
bases = ['A','T','G','C','N']

def get_chr(buf):
    (buf, tmp) = buf.split('>',1)
    if '>' in tmp:
        get_chr(tmp)
    return buf,tmp

with open(args[1],'r') as f:
     tmp = f.readline()
     chr_id = re.split(r'\s',tmp)[0][1:]
     sum_atgc[chr_id] = {}
     for base in bases:
         sum_atgc[chr_id][base] = 0

while 1:
         buffer = f.read(1024 *  1024)
         if not buffer:
            break
         if '>' in buffer:
            #print(len(buffer.split('>')))
            (buffer,tmp) = get_chr(buffer)
            
            buffer = buffer.upper()
            for base in bases:
                sum_atgc[chr_id][base] += buffer.count(base)
            (tmp, buffer) = tmp.split('\n', 1)
            chr_id = re.split(r'\s', tmp)[0][1:]
            sum_atgc[chr_id] = {}
            for base in bases:
                sum_atgc[chr_id][base] = 0
            buffer = buffer.upper()
            for base in bases:
                sum_atgc[chr_id][base] += buffer.count(base)
         else:
            buffer = buffer.upper()
            for base in bases:
                sum_atgc[chr_id][base] += buffer.count(base)

for chr_id,atgc_count in sum_atgc.items():
     print(chr_id)
     GC = int(atgc_count['G']) + int(atgc_count['C'])
     total = sum(atgc_count.values())
     for base in bases:
         print("%s : %s" % (base, atgc_count[base]))
     print( "total : %s" % (total))
     print("CG_per : %s" % (GC/total))
     print("N_per : %s" % (int(atgc_count['N'])/total))

end = time.process_time()
print("time : %s" % (int(end-start)))

==解析1== 使用f.read()读取文件比较慢,通过使用buffer读取可以提升速度,每次读取的字节数为(1024*1024)。对于fasta格式的基因组文件来说,需要区分'>'开头的序列名和序列。首先要读第一行的序列名称tmp=f.readline(),后面的内容就可以按照buffer的要求来读取。一个buffer读入的文件有三种形式:

  • ATCGATGACTGA\n >chr1 \nGCTGATGAC

    1. 包含序列,中间混入一个序列名称
  • ATCGATGCA\n> chrx \nAGCTGATCGATCGATCGATGATCGATGCATGCTA\n >chry \nATGCTAGCTAGTC

    1. 对于某些比较短的染色体来说,可能存在序列中混入了两个序列名称的情况
  • ATCGATGCGGCTAGCTAGCTGATCGAGGCCGATGACG

    1. 只有序列信息,没有序列名称

==解析2== 使用while循环读入buffer时,一定要判断是否有buffer,否则文件读完之后,也不会退出循环

==解析3== 对buffer中含有两个甚至多个以'>'开头的序列名的情况进行处理:最好的解决方式是递归

def get_chr(buf):
    (buf, tmp) = buf.split('>',1)
    if '>' in tmp:
        get_chr(tmp)
    return buf,tmp

文末友情推荐

(0)

相关推荐

  • 转录组学习四(参考基因组及gtf注释探究)

    转录组学习一(软件安装)转录组学习二(数据下载)转录组学习三(数据质控)转录组学习四(参考基因组及gtf注释探究)转录组学习五(reads的比对与samtools排序)转录组学习六(reads计数与标 ...

  • 生信编程3.hg38每条染色体的基因、转录本分布

    有一些五六年前的学生们都成长为了各个生物信息学相关公司的小领导,而且他们都有了自己的公众号,知乎号,也算是一番人物.最近他们跟我反馈面试找不到或者说很难直接考核筛选到认真干活的生信工程师,挺有意思的. ...

  • 生信编程​9.bedtools从bam文件中提取目的序列

    有一些五六年前的学生们都成长为了各个生物信息学相关公司的小领导,而且他们都有了自己的公众号,知乎号,也算是一番人物.最近他们跟我反馈面试找不到或者说很难直接考核筛选到认真干活的生信工程师,挺有意思的. ...

  • 生信编程直播第七题:写超几何分布检验!

    下载数据 切换到工作目录:cd d/生信技能树-视频直播/第七讲 kegg2gene(第六讲kegg数据解析结果) 暂时不用新的kegg注释数据为了能够统一答案 差异基因list和背景基因list 关 ...

  • 生信编程直播课程优秀学员作业展示1

    题目 人类基因组外显子区域长度 学员:x2yline 具体题目详情请参考生信技能树论坛 题目数据来源为:ftp://ftp.ncbi.nlm.nih.gov/pub/CCDS/current_huma ...

  • 生信编程直播课程优秀学员学习心得及作业展示3

    学习感悟 首先说明一下,我不算是完全从0开始学习,因为生物的知识和python的语言之前都知道一点,但说实话,我的python距离真正的实践还差的很远,也没有常用所以基本忘完. 真的很感谢群主和老师们 ...

  • 生信编程直播课程优秀学员作业展示2

    题目:hg19基因组序列的一些探究 学员:x2yline 具体题目详情请参考生信技能树论坛 数据来源:http://hgdownload.cse.ucsc.edu/goldenPath/hg19/bi ...

  • 生信编程直播第0题-生信编程很简单!

    貌似顺序有点怪异,我们都把1~8题给讲解完了,现在才开始第0题,很明显,这个是临时加入的,因为有很多没有编程基础的朋友也开始跟着我们学习了. 还不知道怎么回事的先查看历史题目: 生物信息学技能面试题( ...

  • 生信编程直播第9题-根据指定染色体及坐标得到参考碱基

    还不知道怎么回事的先查看历史题目: 生信编程直播第0题-生信编程很简单! 生物信息学技能面试题(第1题)-人类基因组的外显子区域到底有多长 生物信息学技能面试题(第2题)-探索人类基因组序列 生物信息 ...

  • 生信编程直播第11题:把文件内容按照染色体分开写出

    问题描述这个需求很常见,因为一般生物信息学数据比较大,比如sam,vcf,或者gtf,bed都是把所有染色体综合在一起的文件.如果想根据染色体把大文件拆分成小的文件呢?比如:ftp://ftp.ncb ...