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

如何使用Python将STDF文件数据转换为Pandas DataFrame

Python读取STDF文件并转换为Pandas DataFrame落地方案

不用找所谓“无缺陷、全文档”的现成STDF处理模块,STDF作为半导体测试设备的通用格式,不同厂商(泰瑞达、爱德万、国产测试机等)都会加自定义私有字段,不存在能100%兼容所有文件的通用模块,自己基于现有稳定解析核心搭轻量流程,适配自己的停机时长分析场景,效率和可控性反而更高。

核心依赖选择

  • 解析核心用pystdf,是目前Python生态下对STDF V4标准规范兼容最稳定的实现,核心记录解析逻辑经过量产场景验证,足够覆盖设备运行时长、停机标记、时间戳这类分析需要的字段,文档不全的问题完全可以通过自定义记录处理器绕开,不需要啃全量源码。
  • 数据结构化直接用pandas+numpy做后续时长计算,不需要额外中间格式转换。

具体实现流程

1. 环境安装

直接安装适配Python3的版本即可,执行命令:

pip install pystdf pandas numpy

2. 流式解析代码(支持大文件,低内存占用)

不要用网上那种全量解析所有STDF字段的写法,几个G的量产STDF文件全量解析很容易内存溢出,自定义收集器只抓和设备运行、停机相关的记录,边读边存,解析速度快很多。
最小可用代码如下:

import pandas as pd
import numpy as np
from pystdf import V4
from pystdf.IO import Parser

class StdfRuntimeDataCollector:
    def __init__(self):
        self.records = []
        self.current_lot_start_ts = None

    def send(self, record_type, fields):
        # 仅捕获和运行时长、停机相关的记录类型,跳过无关测试明细数据
        rec_type = record_type.name
        try:
            if rec_type == "MIR":
                # 主信息记录:存批次启动时间戳
                self.current_lot_start_ts = fields[V4.MIR.START_T]
            elif rec_type == "MRR":
                # 主结果记录:存批次结束时间、异常中断标记
                lot_id = fields[V4.MRR.LOT_ID]
                self.records.append({
                    "data_type": "lot",
                    "lot_id": lot_id.decode("utf-8") if isinstance(lot_id, bytes) else lot_id,
                    "start_ts": self.current_lot_start_ts,
                    "end_ts": fields[V4.MRR.FINISH_T],
                    "is_abort": fields[V4.MRR.PART_CNT] == 0
                })
            elif rec_type == "PCR":
                # 暂停计数记录:存批次内停机的起止时间、原因
                pause_rsn = fields[V4.PCR.PAUSE_RSN]
                self.records.append({
                    "data_type": "pause",
                    "start_ts": fields[V4.PCR.START_T],
                    "end_ts": fields[V4.PCR.FINISH_T],
                    "pause_reason": pause_rsn.decode("utf-8") if isinstance(pause_rsn, bytes) else pause_rsn
                })
        except:
            # 碰到厂商自定义字段、格式异常的记录直接跳过,不中断整体解析
            pass

    def to_dataframe(self):
        df = pd.DataFrame(self.records)
        # 时间戳统一转datetime格式方便后续计算
        for col in ["start_ts", "end_ts"]:
            df[col] = pd.to_datetime(df[col], unit="s")
        return df

def read_stdf_to_df(file_path: str) -> pd.DataFrame:
    collector = StdfRuntimeDataCollector()
    parser = Parser(open(file_path, "rb"))
    parser.addSink(collector)
    parser.parse()
    return collector.to_dataframe()

3. 停机时长计算注意事项

拿到结构化DataFrame后,按两类口径统计停机时长即可,避免统计偏差:

  • 批次内停机:筛选data_type == 'pause'的记录,直接计算end_ts - start_ts的时间差求和,就是批次内暂停、故障、待料的时长,可按pause_reason拆分不同停机原因的占比
  • 批次间停机:筛选data_type == 'lot'的记录按start_ts排序,计算上一个批次end_ts到下一个批次start_ts的差值,就是换批、调机、设备空闲的时长
  • 异常停机单独标记:is_abort == True的批次对应的中断时长,单独归类为故障类停机,和正常待料、换批停机分开统计

适配优化提示

如果碰到部分测试机导出的STDF有特殊时间字段、自定义停机标记,只需要在send方法里加对应记录类型的字段提取逻辑就行,不需要修改底层解析代码,适配单厂商机型的规则通常十几行代码就能搞定,比等通用模块适配效率高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:15:51