如何用Python实现两个FASTA文件的序列交集匹配及代码错误修复
Fixing 6mer Reverse Complement Matching Issue Between FASTA Files
Let's break down what's wrong with your code and fix it step by step to get the expected output.
Problem Diagnosis
Your code has three critical issues that caused seq9 to be incorrectly marked as 0 for seq1:
- Wrong window size: You set
window_size = 7, but we're working with 6mers. This miscalculates the loop range, causing you to miss valid 6mers (e.g., only 1 iteration instead of 2 for a 7-length sequence). - Redundant & incorrect reverse complement handling: Using
.split()on the reversed-complemented sequence slice is unnecessary—it splits the sequence into individual characters, which breaks matching entirely. - Early return breaks full inspection: Your function returns immediately after checking the first 6mer. If the first one doesn't match, it never checks the rest, leading to false negatives.
Fixed Code
from Bio import SeqIO import pandas as pd def same_seq(a_record, brecord): window_size = 6 # Iterate through every possible 6mer in the source sequence for j in range(len(a_record.seq) - window_size + 1): # Extract the 6mer, generate its reverse complement, convert to string target_kmer = str(a_record.seq[j:j+window_size].reverse_complement()) # Check if this reverse complement exists in the target sequence if brecord.seq.find(target_kmer) != -1: return True # If no matches found after all checks return False if __name__ == '__main__': records = list(SeqIO.parse("f1.fa", "fasta")) target_records = list(SeqIO.parse("f2.fa", "fasta")) rows_list = [] for target_record in target_records: new_row = {'name': target_record.name} for record in records: # Simplified 1/0 assignment with ternary operator new_row[record.name] = 1 if same_seq(record, target_record) else 0 rows_list.append(new_row) df = pd.DataFrame(rows_list) df = df.set_index(["name"]) print(df)
Key Fixes Explained
- Correct window size: Setting
window_size = 6ensures we loop through all valid 6mers (for a sequence of lengthn, we getn-6+16mers). - Intuitive reverse complement logic: Instead of reversing the entire sequence first, we extract each 6mer individually and generate its reverse complement. This aligns exactly with your requirement to check reverse complements of each source 6mer.
- Proper return logic: The function only returns
Falseafter checking every possible 6mer. If any reverse complement matches the target sequence, it returnsTrueimmediately. - Cleaner code: The ternary operator simplifies the 1/0 assignment, making the code more readable.
Expected Output
Running this fixed code will produce your desired result:
seq1 seq20 seq3 name seq9 1 0 0 seq85 0 1 0
内容的提问来源于stack exchange,提问作者Apex
相关产品推荐
相关产品推荐

