滑动窗口生成蛋白肽段代码运行输出空文件问题排查
固有无序蛋白滑动窗口生成代码异常排查
已定位的具体错误
- 语法缩进错误:Python依靠缩进划分代码块,原代码中
ws_generating函数内部逻辑、遍历蛋白数据的for dt in data循环内部代码均未做缩进,解释器无法识别代码归属,直接触发语法错误,代码无法正常执行。 - 方法拼写错误:解析序列ID的代码写为
dt.fsplit('\n')[0],字符串对象不存在fsplit()方法,仅存在split()方法,运行到该行会直接抛出属性错误。 - 变量作用域错误:
ws_generating函数内部直接使用了循环内定义的sseq(蛋白序列)变量,但该变量未作为参数传入函数,函数作用域无法访问该变量,运行到序列切片逻辑时会抛出变量未定义的错误。 - 标签逻辑错误:需求明确要求用
1标记无序序列、0标记非无序序列,但原代码调用函数时给无序位点传入的标签是'Yes',非无序位点传入的是'No',和标注规则完全不符。 - 多余语法错误:
pd.concat拼接数据的代码行末尾多了一个无意义的双引号",会直接触发语法错误;最后一行写为df_final_result(),将DataFrame对象当作函数调用,这就是运行时提示对象为callable的直接原因——DataFrame是数据结构不是可执行函数,不能加括号调用。 - 方法兼容错误:原代码用
df.append()逐行添加数据,该方法在pandas 2.0及以上版本已被完全移除,就算前置逻辑修正,高版本pandas环境下运行也会抛出方法不存在的错误,无法写入数据,最终导出空文件。 - 文件读取不规范:用
open()打开文件后未做关闭操作,也未使用上下文管理器,可能出现文件内容读取不完整、资源泄漏的问题。 - 边界判断逻辑瑕疵:原代码判断N端padding的条件写为
if neg < window_size,实际当位点索引等于window_size时才不需要N端padding,边界值判断不准会导致首位窗口序列长度不符合预期。
修正后可运行代码
import os import pandas as pd DATA_DIR = 'D:/TMU/spring semester/application of artficial intelligence in genomics/Project 7 - DeepDisoBind' window_size = 5 window_total_len = 2 * window_size + 1 # 中心位点左右各取window_size个残基,总窗口长度固定 def ws_generating(site_list, label, full_seq): # 改用列表收集数据,避免逐行append DataFrame的性能问题和版本兼容问题 sample_list = [] seq_len = len(full_seq) for site in site_list: # 处理N端边界 if site <= window_size - 1: left_pad = '-' * (window_size - site) left_seq = full_seq[:site + window_size + 1] seq_result = left_pad + left_seq # 处理C端边界 elif site >= seq_len - window_size: right_pad = '-' * (window_size - (seq_len - 1 - site)) right_seq = full_seq[site - window_size:] seq_result = right_seq + right_pad # 处理序列中间位点 else: seq_result = full_seq[site - window_size : site + window_size + 1] # 兜底校验窗口长度,避免异常 assert len(seq_result) == window_total_len, f"窗口长度异常,位点{site}生成序列长度为{len(seq_result)}" sample_list.append( (seq_result, label) ) return sample_list # 用上下文管理器读取文件,自动释放资源 all_samples = [] with open(os.path.join(DATA_DIR, 'Training_class.txt'), 'r') as f: fdata = f.read() data = fdata.split('\n>')[1:] for dt in data: dt_lines = dt.strip().split('\n') # 修正fsplit拼写错误 sid = dt_lines[0] sseq = dt_lines[1] smap = dt_lines[2] # 按需求传入0/1标签,同时把蛋白序列作为参数传入函数 pos_sites = [pos for pos, char in enumerate(smap) if char == '1'] neg_sites = [neg for neg, char in enumerate(smap) if char == '0'] all_samples.extend(ws_generating(pos_sites, 1, sseq)) all_samples.extend(ws_generating(neg_sites, 0, sseq)) # 一次性生成最终DataFrame df_final_result = pd.DataFrame(all_samples, columns=['Sequence', 'Label']) # 导出前打印样本量确认数据正常 print(f"共生成{len(df_final_result)}条滑动窗口样本") df_final_result.to_csv(os.path.join(DATA_DIR, 'trainrun.ws05.csv'), index=None) # 查看表头直接调用columns属性,不要加括号 print(df_final_result.columns)
替代优化方案
- 针对fasta格式的带标注蛋白序列,可直接用Biopython的
SeqIO模块做解析,不用手写split逻辑,能自动兼容空行、换行符不统一、序列ID带特殊字符等异常情况,解析稳定性远高于手写字符串切割。 - 如果后续要做无序结合位点的深度学习模型训练,可以把padding字符从
-换成专门的未知氨基酸token,或者用氨基酸编码的默认填充值,避免模型把padding字符当作有效残基学习。 - 大样本量下可以用numpy做序列切片,比纯Python循环生成窗口的速度快3~5倍,适合处理万条以上的蛋白序列数据集。
内容的提问来源于stack exchange,提问作者Rut christine
相关产品推荐
相关产品推荐

