FASTA序列去重脚本遇编码错误及重复统计需求求助
问题本质解析
Word中输入的特殊破折号(如长破折号—、半长破折号–)属于Unicode扩展字符,而非ASCII范围内的普通短横线-。当用Biopython的SeqIO读取FASTA文件时,若未明确指定支持Unicode的编码(默认可能采用系统编码或ASCII),Python会尝试用不兼容的编码解码文件内容,直接触发UnicodeDecodeError。而普通短横线属于ASCII字符集,任何常见编码都能正常解析,因此替换后脚本可正常运行。
修改后的去重脚本(含重复统计)
以下脚本可处理FASTA文件,自动兼容Unicode编码,同时统计重复序列数量,并输出所有重复记录的ID和标题:
from Bio import SeqIO from collections import defaultdict def deduplicate_fasta(input_files, output_file): # 用字典存储序列对应的所有记录,键为序列字符串,值为记录列表 seq_records = defaultdict(list) total_duplicates = 0 # 遍历所有输入FASTA文件 for file in input_files: # 指定utf-8编码读取,避免Unicode解码错误 for record in SeqIO.parse(file, "fasta", encoding="utf-8"): seq_str = str(record.seq) seq_records[seq_str].append(record) # 准备去重后的记录列表 unique_records = [] # 输出重复信息 print("=== 重复序列统计 ===") for seq, records in seq_records.items(): if len(records) > 1: duplicate_count = len(records) - 1 total_duplicates += duplicate_count print(f"序列预览: {seq[:50]}... (总长度{len(seq)})") print(f"重复次数: {duplicate_count}") print("相关记录ID/标题:") for idx, rec in enumerate(records): if idx == 0: print(f" - 保留记录: {rec.id} | {rec.description}") else: print(f" - 重复记录: {rec.id} | {rec.description}") print("---") # 仅保留每个序列的第一条记录 unique_records.append(records[0]) # 写入去重后的FASTA文件 SeqIO.write(unique_records, output_file, "fasta") print(f"\n去重完成!共移除{total_duplicates}条重复序列,去重后文件已保存至{output_file}") # 示例调用 if __name__ == "__main__": input_fastas = ["file1.fasta", "file2.fasta"] # 替换为你的输入文件列表 output_fasta = "deduplicated_sequences.fasta" deduplicate_fasta(input_fastas, output_fasta)
脚本说明
- 读取文件时指定
encoding="utf-8",确保能正确解析含Unicode特殊字符的FASTA标题。 - 使用
defaultdict分组相同序列的所有记录,便于统计重复情况。 - 输出重复序列的详细信息:包括序列预览、重复次数、保留记录和重复记录的ID/标题。
- 最终将去重后的序列写入新的FASTA文件。
内容的提问来源于stack exchange,提问作者Irfan
相关产品推荐
相关产品推荐

