Python 入门之文件操作(一)

上一讲中我们初步认识了python,但是留了个悬念;生物信息中第一个要掌握的基础技能,没错,就是这一讲的文件操作了。

本文就简单介绍一下,生物信息中那些基础的文件读写,后续补充文件权限管理以及文件的移动、复制等操作(先画个饼,有空在填坑)。

文件读写

在日常的生物信息学分析中,我们一般都是直接面对一些文件进行操作的,比如测序数据 fastq文件,在比如比对结果bam或者sam文件,还有 gtf或者gff3格式的注释文件甚至还有一些数据库文件等等。

面对这些文件时候交互式编程会很力不从心,大多数情况下我们都会选择脚本式编程。(关于交互式编程与脚本式编程的区别见另一篇文章,当然现在还没有写!(lll¬ω¬))。

脚本式编程中首先遇到的就是文件的读写,其次是参数的传递。

一般的文件都可以通过open的方式打开,readline的方式进行读取。

# 读文件
f = open('/path/to/file','r') # 只读模式打开
line = f.readline() # 读取一行
linse = f.readlines() # 读取所有行
f.close() # 关闭打开的文件
# 写文件
f = open('/path/to/file','w') # 写模式打开
f.write(string) # 将 string 写入文件中
f.close() # 关闭打开的文件

这里推荐使用with语句,不光可以减少代码量,还可以处理一些异常情况:

with open('/path/to/file','r') as f:
    line = f.readline() # 读取一行
    linse = f.readlines() # 读取所有行

生物信息中一般主流的文件格式有fasta、fastq、sra、Genebank、gtf、gff3、sam、bam等。

fasta文件读写

fasta文件一般以 > 开头,第一行一般为序列名称,或者其他信息之类的,第二行开始为其碱基序列。如下:

# test.fa
>MSTR.8.1 gene=MSTR.8
CCACAATTAATCAGAGGTAGCGACTACCCTATTTCTTCATTTCTTATGATTCTTACTATTTAAGCACTCA
TTTTCCATACCCCCACCTTTTACTTTCCTCTATTTTCCTCTCATCGTTAACTGATTCTGTTCAAGTTATA
GGGTTGGTTCTCAATCCTTGATATGTTGCTGGAATCCCTTTGGATTCGCTAAAAGGAGGATTTCAAGGGT
TTTCCAGAGTTTCCGACATTTGATTAAGGCGATCGGTGGATTTGAACTTGATTTCGATTGTTTCACAGTA
CCACCATGTATGGGTAATCGAGGATTTTAGGGAGGAGAGATTTGAGCCTCAAGGAGGAAGATAACCAGTT
GGTATTTCATGGTAGTAGAATCTTCAGCAATTTCTAGGTATGTTTAGAGGGT
>MSTR.26.1 gene=MSTR.26
CACCAGATCAAGATGACAGTAACTACAATTTAAGCAGATCGAACAGGAAACATGTAGCCATCTTTCATGT
ATGAAAGGTCCAAATACTAGACTCTACTTGTGCATCCCTCAGACTACATTTATTTATCTTGCCGAAATGT
TAAAAATGAAGTTTCAGTTTCTCATGTAAAGTTTAGTTTCAGTTTCATTGAGATGAATCCATGGATGTAG
CTAGTCATCCATTCTCGGGAAACAACAACCACC

对于fasta文件的读取方式,一般有以下两种方法:

  1. 直接读取
    将fasta文件的每一条序列以字典的形式储存起来,字典的键为fasta序列的名称,值为其碱基序列。
#!/usr/bin/evn python
# -*- coding: UTF-8 -*-
with open("test.fa",'r') as fa:
    sequences = {}
    for line in fa:
        if line.startswith(">"):
            name = line.rstrip("\n")
            sequences[name] = ""
        else:
            sequences[name] = sequences[name] + line.rstrip("\n")
    print (sequences)

输出如下:

{'>MSTR.26.1 gene=MSTR.26': 'CACCAGATCAAGATGACAGTAACTACAATTTAAGCAGATCGAACAGGAAACATGTAGCCATCTTTCATGTATGAAAGGTCCAAATACTAGACTCTACTTGTGCATCCCTCAGACTACATTTATTTATCTTGCCGAAATGTTAAAAATGAAGTTTCAGTTTCTCATGTAAAGTTTAGTTTCAGTTTCATTGAGATGAATCCATGGATGTAGCTAGTCATCCATTCTCGGGAAACAACAACCACC', '>MSTR.8.1 gene=MSTR.8': 'CCACAATTAATCAGAGGTAGCGACTACCCTATTTCTTCATTTCTTATGATTCTTACTATTTAAGCACTCATTTTCCATACCCCCACCTTTTACTTTCCTCTATTTTCCTCTCATCGTTAACTGATTCTGTTCAAGTTATAGGGTTGGTTCTCAATCCTTGATATGTTGCTGGAATCCCTTTGGATTCGCTAAAAGGAGGATTTCAAGGGTTTTCCAGAGTTTCCGACATTTGATTAAGGCGATCGGTGGATTTGAACTTGATTTCGATTGTTTCACAGTACCACCATGTATGGGTAATCGAGGATTTTAGGGAGGAGAGATTTGAGCCTCAAGGAGGAAGATAACCAGTTGGTATTTCATGGTAGTAGAATCTTCAGCAATTTCTAGGTATGTTTAGAGGGT'}
  1. 使用第三方模块
    使用 Biopython SeqIO模块,不多使用前好像需要先安装一下,怎么安装请自行google。
#!/usr/bin/evn python
# -*- coding: UTF-8 -*-
from Bio import SeqIO

with open ("test.fa",'r') as fa:
    for record in SeqIO.parse(fa,'fasta'):
        print(record)

输出如下:

ID: MSTR.8.1
Name: MSTR.8.1
Description: MSTR.8.1 gene=MSTR.8
Number of features: 0
Seq('CCACAATTAATCAGAGGTAGCGACTACCCTATTTCTTCATTTCTTATGATTCTT...GGT', SingleLetterAlphabet())
ID: MSTR.26.1
Name: MSTR.26.1
Description: MSTR.26.1 gene=MSTR.26
Number of features: 0
Seq('CACCAGATCAAGATGACAGTAACTACAATTTAAGCAGATCGAACAGGAAACATG...ACC', SingleLetterAlphabet())

正确读取后就可以进行其他需求的操作了。

fastq文件读写

fastq文件格式:,每条序列有4行,第一行一般以 @ 符号开头,主要是测序的一些信息可以简单理解为序列名称,第二行是其碱基序列,第三行也是名称,一般为了节省空间就用 + 号表示,第四行是序列每个碱基的测序质量值,与第二行的碱基一一对应。

@FCD1VGJACXX:2:1101:5762:2000#AAGTCGCG/1
NGGGAGACCGGGGTTCGATTCCCCGACGGGTCGTATGCCGTCTTCTGCT
+
BS\ceeeegggggffgighiiiihhUegiigggeeeeddcccccccccc
@FCD1VGJACXX:2:1101:7844:2000#AAGTCGCG/1
NTGGCTTCCTAAGCCAGGGATTGTGGGTTCGTATGCCGTCTTCTGCTTG
+
BPYa^accgeeggihfhhhfhiQQQQPPPPPP^XYefgeeWaeghhgih

对于fastq文件我们大部分情况下主要考虑其碱基质量,常规情况下,会对其序列进行碱基统计、质量统计等,对于fastq文件,我们同样也有两种方式可以进行读取:

1. 常规方式
#!/usr/bin/evn python
# -*- coding: UTF-8 -*-
# style 1
with open("test.fq",'r') as fq:
    lines = fq.readlines()
    head = [item[:-1] for item in lines[::4]]
    read = [item[:-1] for item in lines[1::4]]
    qual = [item[:-1] for item in lines[3::4]]
    
    sequence = dict(zip(read, qual))
    print(sequence)
    
# style 2
with open('test.fq','r') as fq:
    sequence = {}
    name = None
    for i,line in enumerate(fq):
        if i % 4 == 0:
            name = line.rstrip('\n')
        if i % 4 == 1:
            read = line.rstrip('\n')
        if i % 4 == 3:
            sequence[(name,read)] = line.rstrip('\n')
    for key in sequence:
        print (key[0],key[1],sequence[key])

输出如下:

# style 1
{'NTGGCTTCCTAAGCCAGGGATTGTGGGTTCGTATGCCGTCTTCTGCTTG': 'BPYa^accgeeggihfhhhfhiQQQQPPPPPP^XYefgeeWaeghhgih', 'NGGGAGACCGGGGTTCGATTCCCCGACGGGTCGTATGCCGTCTTCTGCT': 'BS\\ceeeegggggffgighiiiihhUegiigggeeeeddcccccccccc'}
# style 2
('@FCD1VGJACXX:2:1101:5762:2000#AAGTCGCG/1', 'NGGGAGACCGGGGTTCGATTCCCCGACGGGTCGTATGCCGTCTTCTGCT', 'BS\\ceeeegggggffgighiiiihhUegiigggeeeeddcccccccccc')
('@FCD1VGJACXX:2:1101:7844:2000#AAGTCGCG/1', 'NTGGCTTCCTAAGCCAGGGATTGTGGGTTCGTATGCCGTCTTCTGCTTG', 'BPYa^accgeeggihfhhhfhiQQQQPPPPPP^XYefgeeWaeghhgih')
2. 第三方模块读取

与读取fasta文件的模块一样,使用 Biopython

#!/usr/bin/evn python
# -*- coding: UTF-8 -*-
from Bio import SeqIO

with open ("test.fq",'r') as fq:
    for record in SeqIO.parse(fq,'fastq'):
        print(record)

输出如下:

ID: FCD1VGJACXX:2:1101:5762:2000#AAGTCGCG/1
Name: FCD1VGJACXX:2:1101:5762:2000#AAGTCGCG/1
Description: FCD1VGJACXX:2:1101:5762:2000#AAGTCGCG/1
Number of features: 0
Per letter annotation for: phred_quality
Seq('NGGGAGACCGGGGTTCGATTCCCCGACGGGTCGTATGCCGTCTTCTGCT', SingleLetterAlphabet())
ID: FCD1VGJACXX:2:1101:7844:2000#AAGTCGCG/1
Name: FCD1VGJACXX:2:1101:7844:2000#AAGTCGCG/1
Description: FCD1VGJACXX:2:1101:7844:2000#AAGTCGCG/1
Number of features: 0
Per letter annotation for: phred_quality
Seq('NTGGCTTCCTAAGCCAGGGATTGTGGGTTCGTATGCCGTCTTCTGCTTG', SingleLetterAlphabet())

至于sam/bam文件的读取,可以使用第三方模块:pysam ,具体练习在后面遇到了在说。

gtf及gff3注释信息文件的读取与一般文本文件的读取方式一致。

你可能感兴趣的:(Python 入门之文件操作(一))