生物信息之FASTA格式处理
YZDR Lv1

1. 什么是 FASTA 格式?

在生物信息学中,FASTA 是一种用于存储核酸序列或氨基酸序列的文本格式。它简单、通用,主要由两部分组成:

  • 标题行 (Header Line):以大于号 > 开头,包含序列的 ID 和描述信息。

    image-20260113232934994
  • 序列行 (Sequence Lines):紧跟标题行之后的字符序列。需要注意的是,一条序列可能会分布在多个文本行中,这是初学者处理此类文件时最容易掉进去的“坑”。

1
2
#用.strip()来去除后面的换行符(\n)
content = line.strip()

2. Python 原生处理逻辑

处理 FASTA 文件最核心的任务是:将多行序列合并,并与 ID 形成映射关系。我们通常使用 Python 的字典(Dictionary)来存储。

核心代码实现

以下代码展示了如何读取 dna.txt 并将其转换为字典格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
with open('dna.txt', 'r', encoding='utf-8') as f:
f_dict = {}
seq_name = None
for line in f:
content = line.strip() # 去除换行符和首尾空格
if content.startswith('>'):
# 遇到新序列的标题行,截取 ID 并初始化字典值
seq_name = content[1:]
f_dict[seq_name] = ''
else:
# 关键:如果不是标题行,则将序列追加到当前 ID 的值中
# 这样可以自动合并多行显示的序列
f_dict[seq_name] += content

3. Rosalind 经典题目:计算最高 GC 含量

题目背景:在 DNA 序列中,G 和 C 碱基所占的比例(GC-content)对于分析热稳定性及基因组结构至关重要。

任务:给定若干条 FASTA 格式的序列,找出其中 GC 含量最高的一条,并输出其 ID 和百分比。

image-20260113233716797

算法思路

  1. 解析文件:利用上述字典逻辑提取所有序列。
  2. 统计频率:利用 count() 方法计算 G 和 C 的总和。
  3. 比较排序:将结果存入列表并进行降序排列,取首位。

完整解析代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
compare = []

# 遍历解析好的字典
for name, seq in f_dict.items():
# 统计 G 和 C 的数量
gc_count = seq.count('G') + seq.count('C')
# 计算百分比
gc_content = (gc_count / len(seq)) * 100

# 将 (含量, ID) 作为元组存入列表,方便后续排序
compare.append((gc_content, name))
print(f"DEBUG: {name} 的GC含量为: {gc_content:.6f}%")

# 按 GC 含量从高到低排序
compare.sort(reverse=True)

# 获取结果
max_gc_content, max_name = compare[0]

print("-" * 20)
print(f"最高 GC 含量序列 ID: {max_name}")
print(f"GC 含量: {max_gc_content:.6f}")

4. 什么是 FASTQ 格式?

在实际的测序下机数据中,我们更多看到的是 FASTQ 格式。它比 FASTA 多了两项内容:

image-20260113233555698

  1. + 标识符。
  2. 质量值 (Quality Score):对应每个碱基测序的准确度。

FASTQ 逻辑结构(每 4 行为一个单位)

  • Line 1: @ 开头的 ID
  • Line 2: 序列
  • Line 3: +
  • Line 4: 质量字符(如 IIIIHIIII...

5.完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
with open('dna.txt', 'r', encoding='utf-8') as f:
f_dict = {}
seq_name = None
for line in f:
content = line.strip()
if content.startswith('>'):
seq_name = content[1:]
f_dict[seq_name] = ''
else:
f_dict[seq_name] += content

compare = []
print(f_dict)
for name, seq in f_dict.items():
gc_count = seq.count('G') + seq.count('C')
gc_content = gc_count / len(seq) * 100
compare.append((gc_content, name))
print(f"{name} 的GC含量为: {gc_content}%")

compare.sort(reverse=True)
max_gc_content, max_name = compare[0]
print(f" {max_name}\n{max_gc_content}")
 评论
评论插件加载失败
正在加载评论插件