
本文介绍如何使用pandas直接读取psa文本文件,精准筛选以“prod”开头的行、提取第3列数值,并从文件名中正则提取门店号,一步生成结构化csv,无需中间临时文件。
在处理批量工业或业务日志类文件(如 .psa)时,常见需求是:仅解析特定标识行(如 prod)、提取固定位置字段(如第3个逗号分隔值),并关联元信息(如文件名中的门店编号)。传统做法常依赖先写入临时文本再读取,不仅低效,还易引入编码、换行或格式错误。以下提供简洁、健壮、可批量扩展的专业方案。
✅ 核心思路
- 跳过临时文件:pd.read_csv() 支持直接读取原始文件,通过 usecols 指定列索引(0-based),header=None 避免误判首行标题;
- 精准过滤:加载后用布尔索引 df['type'] == 'prod' 筛选目标行,再 drop('type') 移除冗余列;
- 智能提取门店号:利用 re.search(r'store\s+(\d+)', filename) 安全捕获连续数字,兼容 store 15、store_15 等变体;
- 动态列注入:使用 .assign(store=store) 原地添加新列,语义清晰且链式友好。
? 完整可运行代码(支持单文件 & 批量处理)
import pandas as pd
import re
import os
from pathlib import Path
def process_psa_file(filepath: str, output_dir: str = "."):
"""处理单个PSA文件:提取prod行第3列 + 文件名中的store编号"""
# 1. 读取:仅加载第1列(索引0)和第3列(索引2),无表头
df = pd.read_csv(
filepath,
usecols=[0, 2],
header=None,
names=['type', 'num'],
skip_blank_lines=True,
on_bad_lines='skip' # 自动跳过格式异常行(如空行、列数不足)
)
# 2. 过滤 + 清洗:只保留 type=='prod' 的行,并移除 type 列
df = df[df['type'] == 'prod'].drop(columns='type').reset_index(drop=True)
# 3. 提取 store 编号(推荐:更鲁棒的正则)
filename = Path(filepath).stem
store_match = re.search(r'(?:store|STORE)[\s_-]*(\d+)', filename)
store_num = store_match.group(1) if store_match else "unknown"
# 4. 添加 store 列并导出
df = df.assign(store=store_num)
output_path = Path(output_dir) / f"{Path(filepath).stem}_output.csv"
df.to_csv(output_path, index=False)
print(f"✅ 已保存: {output_path} (共 {len(df)} 条记录)")
# ? 批量处理 ZIP 内所有 .psa 文件(需先解压)
psa_folder = "path/to/your/psa_files" # 替换为实际路径
for psa_file in Path(psa_folder).glob("*.psa"):
process_psa_file(psa_file, output_dir="output_csv")
# ? 若需直接处理 ZIP(不解压),可结合 zipfile 模块:
# import zipfile
# with zipfile.ZipFile("data.zip") as z:
# for name in z.namelist():
# if name.endswith(".psa"):
# with z.open(name) as f:
# # 注意:pd.read_csv 不直接支持 zip file object,需 BytesIO 转换
# # 此处略去,详见 pandas 文档关于 buffer 的说明⚠️ 关键注意事项
- 列索引务必从0开始计数:usecols=[0,2] 对应第1列(prod/pla)和第3列(目标数值),而非 [1,3];
- 正则容错设计:(?:store|STORE) 匹配大小写,[\s_-]* 兼容空格、下划线、短横线分隔,避免因命名不规范导致提取失败;
- 异常处理必备:on_bad_lines='skip' 和 skip_blank_lines=True 防止文件末尾空行或损坏行中断流程;
- 批量命名安全:使用 Path(filepath).stem 获取无后缀文件名,避免 os.path.split() 的平台差异风险。
✅ 输出效果示例
输入文件 1 Area 2 - store 15 group.psa 处理后生成:
num,store 456,15 789,15
完全匹配预期表格结构,且天然支持多文件并行处理——只需修改 psa_folder 路径,即可一键处理整个门店数据集。









