You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结构化解析codeml输出文件并转换为表格格式

报错根因
  • 原代码循环遍历到lines列表末尾时,直接访问i+1/i+3/i+4位置的元素,当i距离列表末尾小于4时,这些索引不存在,直接触发列表越界报错
  • ID判定逻辑过于宽松:只要行内包含"OG"字符串就认定为目标ID行,很容易把结果块内其他带OG字符的说明文字误判为ID行,后续取数完全错位
  • 空行判定逻辑错误:代码写的是判断 "\\n" not in lines[i+1],实际匹配的是字面量\n字符串,不是空行,判定条件完全失效
  • 依赖固定行偏移取数:不同OG对应的结果块之间空行数量、说明行长度可能有差异,固定取ID行后第3、4行的内容,很容易取到非目标行
修正后的解析方案

放弃固定行偏移取数的逻辑,先过滤空行,再逐行扫描匹配ID和对应参数,从根源避免越界和错位问题,可直接运行:

import pandas as pd
import re

# 读取文件并提前过滤纯空行,避免空行打乱匹配逻辑
lines = []
with open("/home/Selection_Analysis/M0_res.txt", mode='r') as f:
    for line in f:
        stripped_line = line.strip()
        if stripped_line:
            lines.append(stripped_line)

res = []
current_record = None

# 预编译正则匹配规则,适配codeml标准输出格式
og_id_pattern = re.compile(r'^(OG\d+_M0)')
lnl_pattern = re.compile(r'lnL\s*=\s*([-\d.]+)')
base_param_pattern = re.compile(r't=\s*([\d.]+)\s+S=\s*([\d.]+)\s+N=\s*([\d.]+)')
omega_pattern = re.compile(r'dN/dS\s*=\s*([\d.]+)')
dn_pattern = re.compile(r'dN\s*=\s*([\d.]+)')
ds_pattern = re.compile(r'dS\s*=\s*([\d.]+)')

for line in lines:
    # 匹配到新的OG ID时,先把上一个采集完成的记录存入结果,再初始化新记录
    id_match = og_id_pattern.search(line)
    if id_match:
        if current_record is not None:
            res.append(current_record)
        current_record = {
            "ID": id_match.group(1),
            "lnL": None,
            "t": None,
            "S": None,
            "N": None,
            "dN/dS": None,
            "dN": None,
            "dS": None
        }
        continue

    # 未匹配到第一个ID前跳过参数匹配
    if current_record is None:
        continue

    # 逐行匹配当前ID对应块内的各个参数
    lnl_match = lnl_pattern.search(line)
    if lnl_match:
        current_record["lnL"] = float(lnl_match.group(1))
        continue

    base_match = base_param_pattern.search(line)
    if base_match:
        current_record["t"] = float(base_match.group(1))
        current_record["S"] = float(base_match.group(2))
        current_record["N"] = float(base_match.group(3))
        continue

    omega_match = omega_pattern.search(line)
    if omega_match:
        current_record["dN/dS"] = float(omega_match.group(1))
        continue

    dn_match = dn_pattern.search(line)
    if dn_match:
        current_record["dN"] = float(dn_match.group(1))
        continue

    ds_match = ds_pattern.search(line)
    if ds_match:
        current_record["dS"] = float(ds_match.group(1))
        continue

# 循环结束后存入最后一条记录
if current_record is not None:
    res.append(current_record)

# 转换为结构化表格并导出
df = pd.DataFrame(res)
df.to_csv("codeml_M0_parsed_result.csv", index=False, encoding="utf-8")
方案说明
  • 提前过滤所有纯空行,避免空行导致的行号错位问题
  • 用正则严格匹配OG ID格式,不会把带OG字符的普通说明行误判为ID行
  • 不依赖固定行偏移,按参数本身的文本特征匹配取值,适配codeml不同版本输出的微小格式差异
  • 全程不会访问超出列表长度的索引,从根源解决IndexError问题
  • 最终输出为标准pandas DataFrame,可直接导出为csv文件做后续统计分析

内容的提问来源于stack exchange,提问作者peg97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:55:01