使用Python计数fasta文件中每个基因中特定字符的出现次数

0 投票
2 回答
1532 浏览
提问于 2025-04-17 16:42

我有一个fasta文件,内容如下:

>SO_0001 
MTKIAILVGTTLGSSEYIADEMQAQLTPLGHEVHTFLHPTLDELKPYPLWILVSSTHGAGDLPDNLQPFC
KELLLNTPDLTQVKFALCAIGDSSYDTFCQGPEKLIEALEYSGAKAVVDKIQIDVQQDPVPEDPALAWLA
QWQDQI
>SO_0002  
MTTPVDAPKWPRQIPYIIASEACERFSFYGMRNILTPFLMTALLLSIPEELRGAVAKDVFHSFVIGVYFF
PLLGGWIADRFFGKYNTILWLSLIYCVGHAFLAIFEHSVQGFYTGLFLIALGSGGIKPLVSSFMGDQFDQ
>SO_0003 
MTTDTIVAQATAPGRGGVGIIRISGDKATNVAMAVLGHLPKPRYADYCYFKSASGQVIDQGIALFFKGPN
SFTGEDVLELQGHGGQIVLDMLIKRVLEVEGIRIAKPGEFSEQAFMNDKLDLTQAEAIADLIDATSEQAA
KSALQSLQGEFSKEVHELVDQVTHLRLYVEAAIDFPDEEVD

在这个文件中,">"后面的是基因ID,而紧接着">"这一行的字母则是对应的序列。我想要逐行读取这个文件,统计每个基因ID对应的序列中有多少个"C"字母。我希望输出的文件格式是用制表符分隔的,像这样:

SO_0001    Number of C's
SO_0002    Number of C's
SO_0003    Number of C's

还有其他类似的内容...

我正在使用Python,原本以为这很简单,可以把基因ID当作字典的键,但我之前只处理过用制表符分隔的文件,现在遇到麻烦了,因为每个序列的长度不同,而且它们都在基因ID的下面。有什么建议吗?

2 个回答

4

搜索 biopython fasta 会出现 这个页面,然后我们可以修改里面的例子:

>>> from Bio import SeqIO
>>> with open("bio.fasta") as fp:
...         record_dict = SeqIO.to_dict(SeqIO.parse(fp, "fasta"))
...     

这样会生成一个看起来像这样的数据字典:

>>> import pprint
>>> pprint.pprint(record_dict)
{'SO_0001': SeqRecord(seq=Seq('MTKIAILVGTTLGSSEYIADEMQAQLTPLGHEVHTFLHPTLDELKPYPLWILVS...DQI', SingleLetterAlphabet()), id='SO_0001', name='SO_0001', description='SO_0001', dbxrefs=[]),
 'SO_0002': SeqRecord(seq=Seq('MTTPVDAPKWPRQIPYIIASEACERFSFYGMRNILTPFLMTALLLSIPEELRGA...FDQ', SingleLetterAlphabet()), id='SO_0002', name='SO_0002', description='SO_0002', dbxrefs=[]),
 'SO_0003': SeqRecord(seq=Seq('MTTDTIVAQATAPGRGGVGIIRISGDKATNVAMAVLGHLPKPRYADYCYFKSAS...EVD', SingleLetterAlphabet()), id='SO_0003', name='SO_0003', description='SO_0003', dbxrefs=[])}

我们可以通过这个字典来访问记录并计算字符的数量:

>>> record_dict["SO_0002"]
SeqRecord(seq=Seq('MTTPVDAPKWPRQIPYIIASEACERFSFYGMRNILTPFLMTALLLSIPEELRGA...FDQ', SingleLetterAlphabet()), id='SO_0002', name='SO_0002', description='SO_0002', dbxrefs=[])
>>> record_dict["SO_0002"].seq
Seq('MTTPVDAPKWPRQIPYIIASEACERFSFYGMRNILTPFLMTALLLSIPEELRGA...FDQ', SingleLetterAlphabet())
>>> record_dict["SO_0002"].seq.count("C")
2

接下来:

>>> count = {name: record.seq.count("C") for name, record in record_dict.items()}
>>> count
{'SO_0002': 2, 'SO_0003': 1, 'SO_0001': 3}

然后:

>>> import csv
>>> with open("c_count.csv", "wb") as fp:
...     writer = csv.writer(fp, delimiter="\t")
...     for k in sorted(count):
...         writer.writerow([k, count[k]])

会生成一个像这样的文件:

localhost-2:coding $ cat c_count.csv 
SO_0001 3
SO_0002 2
SO_0003 1

建议:不要自己重新写一个 FASTA 解析器,直接使用现有的;还有,不要重新实现 csv 模块。

0

如果你已经有了你发的那种格式的数据,并且不想去研究那些专业的库,你可以试试下面这个方法。

with open('datafile.txt') as file:
  datalist = []
  for line in file:
    if line.startswith('>'):
      datalist.append([line.strip()[1:], ''])
    else:
      datalist[-1][1] += line.strip()
  for data in datalist:
    print(data[0], '   ', data[1].count('C'))

撰写回答