用python分割fastq文件的腳本(自寫)

嘮嘮叨叨:

因?yàn)樘幚鞟TAC-seq的原始fastq數(shù)據(jù)太大(已知GEO號(hào)在ncbi上下載),所以被老師要求用python編程分割fastq腳本,其實(shí)用軟件seqkit就可以進(jìn)行分割,命令簡單還快速,想分多少份就分多少份,但老師說我不練怎么會(huì)編程呢,所以沒辦法,我這剛?cè)腴T的小白,就在網(wǎng)上各種查資料,發(fā)現(xiàn)都是處理fasta格式的,因?yàn)閒astq格式和fasta格式并不一樣,不知道可以借鑒不,日夜研究別人的代碼,以及翻找網(wǎng)絡(luò),讀到一篇將fastq文件寫入和讀出的代碼,理解并做出了嘗試,然后又絞盡腦汁如何進(jìn)行分割,后來想到按行分配,只是需要每次都查看一下文件有多少行,然后又搜了一下代碼,想把兩者結(jié)合起來,中間報(bào)了各種error,就反復(fù)調(diào)試,7.1的那一天上午成功了,但是我取的是10000行,不知道生成的文件為什么是7000多行,沒找到原因,沒有打開生成的文件看看,下午老師過來看我發(fā)現(xiàn)是沒有加換行符的問題,實(shí)際上輸出是對(duì)的

分割fastq腳本:

需要引入時(shí)間函數(shù)(此處參考網(wǎng)上),可以看腳本分割用了多久

gz文件打開需要引入gzip函數(shù)

from datetime import datetime

import re

import sys

def Main():#定義函數(shù),讀入fastq文件

? ? source_dir = sys.argv[1] #傳入的參數(shù)1:目標(biāo)文件夾所在目錄

? ? read_number=int(sys.argv[2]) #傳入的參數(shù)2:需要分割的行數(shù),需要是4的倍數(shù),腳本里需要驗(yàn)證一下

? ? target_dir = sys.argv[3]#傳入的參數(shù)3:分割后文件所在的目錄

? ? #print(target_dir)

? ? fas={}

? ? id=None

? ? name = 1

? ? N=0 #讀取數(shù)據(jù)的行數(shù)數(shù)值,初始值為0

? ? if read_number%4 != 0:

? ? ? print("參數(shù)錯(cuò)誤,程序退出")

? ? ? sys.exit()

? ? else:

? ? ? print("開始。。。。。")

? ? ? print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

? ? ? with gzip.open(source_dir,'rb') as f:

? ? ? ? ? for line in f:

? ? ? ? ? ? N+=1

? ? ? ? ? ? if line.decode()[0]=="@":

? ? ? ? ? ? ? ? id=line.decode().strip().split()[0][1:]#對(duì)二進(jìn)制文件進(jìn)行解碼

? ? ? ? ? ? ? ? fas[id]=[]? #將該id對(duì)應(yīng)的初始值為空

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? seq=fas[id].append(line.decode())?

? ? ? ? ? ? ? ? #print(fas)

? ? ? ? ? ? if N==read_number:

? ? ? ? ? ? #? with gzip.open(target_dir+'/57.%04d.fq.gz'%(name),'wb') as out:

? ? ? ? ? ? ? ? #? print(target_dir+'/57.%04d.fq.gz'%(name))

? ? ? ? ? ? ? ? ? ? if re.findall('r1', source_dir, flags=re.IGNORECASE):? #正則匹配可以不區(qū)分大小寫 或直接判斷R1是否在source_dir里,需大寫:if R in source_dir:

? ? ? ? ? ? ? ? ? ? ? ? with gzip.open(target_dir+'.R1.%04d.fq.gz'%(name),'wb') as out:

? ? ? ? ? ? ? ? ? ? ? ? ? ? print(target_dir+'.R1.%04d.fq.gz'%(name))

? ? ? ? ? ? ? ? ? ? ? ? ? ? for id,seq in fas.items():?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? res = '@'+id+"/1"+"\n"+seq[0]+seq[1]+seq[2]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? out.write(res.encode())

? ? ? ? ? ? ? ? ? ? ? ? name+=1

? ? ? ? ? ? ? ? ? ? ? ? N=0

? ? ? ? ? ? ? ? ? ? ? ? fas={}

? ? ? ? ? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? ? ? ? with gzip.open(target_dir+'.R2.%04d.fq.gz'%(name),'wb') as out:

? ? ? ? ? ? ? ? ? ? ? ? ? ? print(target_dir+'.R2.%04d.fq.gz'%(name))

? ? ? ? ? ? ? ? ? ? ? ? ? ? for id,seq in fas.items():

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? res = '@'+id+"/2"+"\n"+seq[0]+seq[1]+seq[2]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? out.write(res.encode())

? ? ? ? ? ? ? ? ? ? ? ? name+=1

? ? ? ? ? ? ? ? ? ? ? ? N=0

? ? ? ? ? ? ? ? ? ? ? ? fas={}

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? continue


? ? ? print("完成。。。。。")

? ? ? print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

if __name__ == "__main__":

? ? Main()

優(yōu)化:此腳本由我的導(dǎo)師提出幾個(gè)優(yōu)化步驟又進(jìn)行改進(jìn),以上是完整版,改進(jìn)為:一傳入?yún)?shù);二對(duì)傳入的文件名進(jìn)行判斷是含R1還是R2,如果含R1在文件的read_name后加上/1,反之R2加上/2;三將輸出的文件名的數(shù)固定住

對(duì)于我的腳本有一些缺陷:如果文件生于的行數(shù)怎么辦,雖然此腳本有考慮到,但我沒運(yùn)行成功,二就是分割的時(shí)間太慢

7月的第一天,我一個(gè)小白能寫出腳本感覺異常欣慰,二是班長通知六級(jí)報(bào)名,而我去年六級(jí)竟然裸考過了,終于不用再去奔赴六級(jí)的考場(chǎng)了,哈哈,開心,感謝我讀過的英文文獻(xiàn)

老師版:

第二天我們老師在我旁邊又教我寫出另一個(gè)版本,即按read數(shù)進(jìn)行分割fastq文件,不得不說我們老師真厲害,代碼比我簡潔多了,而且教我寫出只用了一個(gè)小時(shí),時(shí)間上也會(huì)慢些,應(yīng)該是文件較大,但是不用考慮剩余行的問題,只需要提前計(jì)算好分割的reads數(shù)

import gzip

from datetime import datetime

import re

import sys

def Main():

? ? test_R1=False

? ? test_R2=False

? ? source_dir = sys.argv[1]

? ? read_number=int(sys.argv[2])

? ? target_dir = sys.argv[3]

? ? #print(target_dir)

? ? fas={}

? ? id=None

? ? name = 1

? ? N=0 #讀取數(shù)據(jù)的行數(shù)數(shù)值,初始值為0

? ? print("開始。。。。。")

? ? print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

? ? with gzip.open(source_dir,'rb') as f:

? ? ? for line in f:

? ? ? ? if N%(4*read_number)==0:

? ? ? ? ? ? if re.findall('r1', source_dir, flags=re.IGNORECASE):

? ? ? ? ? ? ? ? ? f_out = gzip.open(target_dir+'.R1.%04d.fq.gz'%(name),'wb')

? ? ? ? ? ? ? ? ? print(target_dir+'.R1.%04d.fq.gz'%(name))

? ? ? ? ? ? ? ? ? test_R1 = True

? ? ? ? ? ? ? ? ? suffix="/1"

? ? ? ? ? ? elif re.findall('r2', source_dir, flags=re.IGNORECASE):

? ? ? ? ? ? ? ? ? f_out = gzip.open(target_dir+'.R2.%04d.fq.gz'%(name),'wb')

? ? ? ? ? ? ? ? ? print(target_dir+'.R2.%04d.fq.gz'%(name))

? ? ? ? ? ? ? ? ? test_R2= True

? ? ? ? ? ? ? ? ? suffix="/2"

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? print("Error: R1 or R2 in filename not detected,exit")

? ? ? ? ? ? ? ? ? sys.exit()

? ? ? ? ? ? name+=1?

? ? ? ? N+=1

? ? ? ? if N%4==1:

? ? ? ? ? ? if test_R1:

? ? ? ? ? ? ? ? if re.findall('/1', line.decode(), flags=re.IGNORECASE):

? ? ? ? ? ? ? ? ? ? f_out.write(line)

? ? ? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? ? f_out.write((line.decode().strip().split()[0]+suffix+"\n").encode())

? ? ? ? ? ? if test_R2:

? ? ? ? ? ? ? ? ? if re.findall('/2', line.decode(), flags=re.IGNORECASE):

? ? ? ? ? ? ? ? ? ? f_out.write(line)

? ? ? ? ? ? ? ? ? else:

? ? ? ? ? ? ? ? ? ? f_out.write((line.decode().strip().split()[0]+suffix+"\n").encode())

? ? ? ? elif N%4==3:

? ? ? ? ? ? f_out.write(("+\n").encode())

? ? ? ? else:

? ? ? ? ? ? f_out.write(line)


? ? print("完成。。。。。")

? ? print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

if __name__ == "__main__":

? ? Main()

這兩段代碼都已運(yùn)行成功

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容