ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AFT二次开发教程(12):多场景输出聚合与对比——透视表、差值与包络

AFT二次开发教程(12):多场景输出聚合与对比——透视表、差值与包络 AFT二次开发教程12多场景输出聚合与对比——透视表、差值与包络版本与事实声明产品与版本AFT Fathom 15 / AFT Impulse 12当前多场景输出与导出规则引用官方Fathom 13帮助页与官方博客正文当前版以官方文档为准。语言/环境Python 3.xpandas openpyxl。本文目标读完能把 N 个场景的导出件收成场景×对象透视表并算出相对基准的差值与极值包络形成可直接进报告的结论表。所有数值为示例性建模。一句话结论AFT 的多场景输出通常需要模型文件内生成输出官方博客明确多场景输出需.out输出文件否则面板可能看不到全部场景而把多场景结果一次收进 Excel 有两条硬约束多 sheet 只能每场景独立工作簿 / 单 sheet 才能多场景同簿聚合的标准动作是 —— 把各场景长表按 (object, parameter) 透视、再对基准场景算差值/百分比、并对全部场景算极值包络得到最不利工况落在哪里的工程结论。〇、本篇要解决的认知问题Q1为什么有时候多场景输出面板里看不到某些场景的数据.out文件是什么角色Q2把多场景结果收进一份 Excel到底该选单 sheet还是多 sheet 多工作簿两条硬约束怎么落到操作上Q3几十个场景的结果怎么变成能判读的表透视、差值、包络Q4什么是包络它在管网设计里解决什么问题Q5官方 Scenario Comparison Tool 与我的 Python 聚合脚本各自该用在什么时候一、机制解析12.1 多场景输出的先决条件.out输出文件官方博客在讲查看多场景输出时给出一条关键事实为了最小化文件体积AFT Arrow 与 AFT Fathom 通常把输出存在模型文件里。要显示多场景输出就必须创建输出文件.out文件。第一次选择多场景输出时你可能看不到所有文件的输出因为输出文件还没生成。解决办法是要么逐个加载并运行各场景要么用 File 菜单的 Start Batch Run 重跑一遍。工程解读单场景时输出藏在模型文件里是省空间的好设计多场景汇总视图需要显式的.out文件而它是跑出来的所以我明明跑过为什么看不到的答案通常是——当时还没生成.out或者那次跑的是只加载没运行。这条直接决定了你的批跑流程想汇总多场景 →必须用 Start Batch Run 实打实跑一遍而不是只加载跑完.out才齐。12.2 多场景导出的两条硬约束怎么落到操作上第 06 篇讲过两条铁律 9这里给决策你的目标Excel Export Manager 配置结果一份汇总工作簿推荐只指定一个 sheet所有场景落在同一张表一次读回多表精美版式KPI明细图指定多个 sheet必须每场景一个工作簿事后合并只需要补齐某些场景导出用Export Only (Do Not Run)复用已有输出但无输出的场景不会导出最佳实践汇总优先用单 sheet。它让一次读回成为可能第 11 篇的to_long直接吃代价是版式朴素等要出交付件时第 19 篇再由 Python 生成精美版式——把取数和排版彻底解耦。12.3 三种聚合视角拿到长表后聚合有三个视角对应三个工程问题视角操作回答的问题透视pivot(object, parameter)×scenario每个对象每个参数在各工况下是多少差值delta相对基准场景做差/百分比相对设计工况变化了多少包络envelope对全部场景取max/min并记录出现在哪个场景最不利工况是哪个包络是关键管网设计要回答的不是某个工况行不行而是所有工况里最坏的情况有多坏、发生在哪。所以包络表要同时给极值和极值所在场景一句idxmax不够要idxmax 取值。12.4 与官方 Scenario Comparison Tool 的分工官方另有Scenario Comparison Tool / Grid把多场景输入输出并排比对适合工程师在选型会上现场研判Few 场景、人工判读、看重交互。分工建议经验法则≤ 5 个场景 人工研判→ 用官方Scenario Comparison Tool几十上百场景 进库/报表/画包络→ 用Python 聚合本篇两者都要→ Python 出结论表GUI 工具做逐项复核。12.5 三个聚合陷阱聚合看着简单透视、做差、取极值但有三处会静默出错陷阱一把不同单位的对象混在一起取极值。若你把压力这个参数名下的所有对象一锅端地取max而其中混了psia与bar得到的最大值毫无物理意义。对策groupby必须带unit本篇代码的做法。陷阱二基准场景选错。差值是相对基准的基准选谁决定了整张表的判读。若基准工况本身是个异常工况所有差值都会失真。对策基准必须是名义设计工况并在结果里显式写出基准场景的路径名第 19 篇的交付件必须带这条。陷阱三用max()而不记idxmax()。只拿到最大值 128没用工程要的是最大值 128 出现在 HighSpeed 工况。对策极值必须成对输出值 场景本篇envelope的做法。经验法则聚合的每一步都要能指回一个具体场景。任何不能指回场景的聚合结果都不具备工程可用性——因为你无法据此做任何决策不知道该调哪个工况、该改哪台设备。二、完整代码与逐行剖析代码 12-1aggregate.py长表 → 透视 / 差值 / 包络# -*- coding: utf-8 -*- aggregate.py —— 多场景长表聚合透视表 相对基准差值 极值包络 输入长表列scenario, object, parameter, unit, value 运行 python aggregate.py --selftest python aggregate.py long_all.csv --base Base Scenario\\US Units\\Design --out agg.xlsx importargparseimportsysimportpandasaspddefpivot(long:pd.DataFrame,parameter:str)-pd.DataFrame:某一参数行object列scenario值value。sublong[long[parameter]parameter]returnsub.pivot_table(index[object,unit],columnsscenario,valuesvalue)defdelta(pv:pd.DataFrame,base:str)-pd.DataFrame:相对基准场景的差值与百分比。ifbasenotinpv.columns:raiseKeyError(f基准场景不在结果中{base})outpd.DataFrame(indexpv.index)out[base]pv[base]forcinpv.columns:ifcbase:continueout[fd_{c}]pv[c]-pv[base]with_ratiopv[base].replace(0,pd.NA)out[fpct_{c}](pv[c]-pv[base])/with_ratio*100.0returnoutdefenvelope(long:pd.DataFrame,parameter:str)-pd.DataFrame:每一 (object, unit)最大值/最小值及其所在场景。sublong[long[parameter]parameter].dropna(subset[value])recs[]for(obj,unit),ginsub.groupby([object,unit]):gg.reset_index(dropTrue)i_max,i_ming[value].idxmax(),g[value].idxmin()recs.append({object:obj,unit:unit,max_value:g.loc[i_max,value],max_scenario:g.loc[i_max,scenario],min_value:g.loc[i_min,value],min_scenario:g.loc[i_min,scenario],span:g.loc[i_max,value]-g.loc[i_min,value]})returnpd.DataFrame(recs).sort_values(span,ascendingFalse)defselftest():rows[]data{rB\Design:{P3:120.0,P4:121.0},rB\LowSpeed:{P3:112.0,P4:113.0},rB\HighSpeed:{P3:128.0,P4:120.0},}forscn,valsindata.items():forobj,vinvals.items():rows.append({scenario:scn,object:obj,parameter:pressure,unit:psia,value:float(v)})longpd.DataFrame(rows)pvpivot(long,pressure)assertpv.loc[(P3,psia),rB\HighSpeed]128.0ddelta(pv,rB\Design)assertabs(d.loc[(P3,psia),rd_B\HighSpeed]-8.0)1e-9# 128-120envenvelope(long,pressure)p3env[env[object]P3].iloc[0]assertp3[max_scenario]rB\HighSpeedandp3[min_scenario]rB\LowSpeedassertabs(p3[span]-16.0)1e-9# 128-112print(SELFTEST OK透视/差值/包络三者数值与极值所在场景均正确。)defmain():apargparse.ArgumentParser()ap.add_argument(long_csv,nargs?)ap.add_argument(--param,defaultpressure)ap.add_argument(--base,requiredFalse)ap.add_argument(--out,defaultagg.xlsx)ap.add_argument(--selftest,actionstore_true)aap.parse_args()ifa.selftestornota.long_csv:selftest()return0longpd.read_csv(a.long_csv,encodingutf-8-sig)pvpivot(long,a.param)envenvelope(long,a.param)withpd.ExcelWriter(a.out,engineopenpyxl)asw:pv.to_excel(w,sheet_namefpivot_{a.param})env.to_excel(w,sheet_namefenvelope_{a.param},indexFalse)ifa.base:delta(pv,a.base).to_excel(w,sheet_namefdelta_vs_base)print(f已写出{a.out}透视 / 包络( / 差值ifa.baseelse))return0if__name____main__:sys.exit(main())逐行剖析pivot()的 index 用[object,unit]单位进 index这样即便某个参数在不同导出里单位不同也不会被错误合并——聚合阶段也要守住单位。delta()里with_ratio pv[base].replace(0, pd.NA)防止除零。压力/流量在极端工况下可能为 0直接除会得到inf污染整表。envelope()同时输出 max_value/max_scenario 与 min_value/min_scenario——这是本篇最重要的设计只给极值不给场景工程上没用“最不利是 128不如最不利是 128出现在 HighSpeed 工况”。span极差排序让波动最大的对象排在最前直接指向风险点。groupby([object,unit])按对象单位分组求包络避免把不同单位的对象混在一起取极值。selftest()三个断言覆盖三种视角透视取点、差值128-1208、包络128/112、span16、极值场景名。每个都是可手算复核的数。代码 12-2merge_books.py多工作簿合并 → 单长表# -*- coding: utf-8 -*- merge_books.py —— 把每场景一个工作簿的导出件合并成一张总长表 用于无法改成单 sheet 的场景每个工作簿名即场景号 运行python merge_books.py --selftest importglobimportosimportsysimportpandasaspddefmerge(files:list,reader)-pd.DataFrame:files: 工作簿路径列表reader: 把单文件读成长表的函数。frames[]forfinfiles:scnos.path.splitext(os.path.basename(f))[0]# 文件名当场景名dfreader(f)df[scenario]scn frames.append(df)returnpd.concat(frames,ignore_indexTrue)ifframeselsepd.DataFrame()defselftest():deffake_reader(path):# 模拟每个工作簿一个场景2 个对象returnpd.DataFrame([{object:P3,parameter:pressure,unit:psia,value:120.0},{object:P4,parameter:pressure,unit:psia,value:121.0}])outmerge([HighSpeed.xlsx,LowSpeed.xlsx],fake_reader)assertlen(out)4,len(out)# 2 文件 × 2 对象assertset(out[scenario]){HighSpeed,LowSpeed}print(SELFTEST OK2 工作簿 × 2 对象 4 行场景名取自文件名。)if__name____main__:if--selftestinsys.argv:selftest()逐行剖析场景名取自文件名这是唯一在每场景一个工作簿模式下能可靠恢复场景身份的途径所以批跑导出时要把文件名规范成场景名第 10 篇的命名纪律在这里兑现。reader作为参数注入把读单个工作簿的逻辑第 11 篇的to_long传进来merge只管拼接。依赖注入让这个函数可测试selftest 里用 fake_reader。pd.concat前先取场景名再拼顺序正确——先打标再合并不能反。三、常见报错与排查报错 12-1多场景输出面板里有些场景没数据。现象跑过的场景看不到。根因多场景输出需要.out输出文件它要么没生成要么那次只是加载未运行。解法用Start Batch Run实跑一遍以生成.out。报错 12-2改成每场景一个工作簿后合并时场景名全丢了。现象合并后分不清哪个是哪个。根因场景名没编码进文件名。解法批跑导出时把输出文件名规范为场景名合并时以文件名当场景名代码 12-2。报错 12-3差值列出现inf或百分比爆表。现象pct_*列有 inf。根因基准场景某对象值为 0做了除法。解法replace(0, pd.NA)或改用绝对差值表述对 0 基准工况单独标注。报错 12-4包络结果看着合理但最不利工况找不到。现象只看到极值数字。根因只取了max()没取极值所在场景。解法用idxmax()/idxmin()记下场景代码 12-1 的envelope。报错 12-5批跑期间打开目标工作簿导出失败。现象某场景后报写入失败。根因批处理模式每场景保存一次撞文件锁。解法批跑期间不打开目标工作簿第 06/10 篇。报错 12-6包络的最大值是个假值——混了单位。现象极值明显不合理量级差一个数量级。根因聚合时把不同unit的对象混在一起取极值如psia与bar混算。解法groupby必须带unit聚合前做一次同参数单位集合检查第 11 篇练习 3。四、动手练习练习 1聚合自检跑python aggregate.py --selftest。判定输出SELFTEST OK手工复核 128-1208 与 128-11216 两个数。练习 2真实聚合用第 11 篇的总长表跑--param pressure --base 你的基准场景。判定得到透视、包络、差值三张表包络表按span降序第一条就是波动最大的对象。练习 3多工作簿合并在每场景一个工作簿模式下导出 3 个场景合并成总长表。判定合并后scenario有 3 个取值且等于文件名总行数 3 × 对象数 × 参数数。练习 4结论抽取从包络表里找出最不利对象并写一句工程结论。判定结论句含对象名 极值 所在场景三要素例如P3 压力极差最大最不利出现在 HighSpeed 工况。练习 5陷阱排查故意构造一份同一 parameter 混两种 unit的长表跑包络。判定观察到的极值是否荒谬用groupby([object,unit])修正后重跑写出修正前后的极值差。五、小结与下一篇预告本篇把多场景收成了结论多场景输出需要.out输出文件要实跑多场景导出有两条硬约束汇总优先单 sheet / 多 sheet 就每场景一簿再合并聚合三视角——透视、相对基准差值、极值包络其中**包络必须带上极值所在场景**才有工程价值与官方 Scenario Comparison Tool 的分工是少场景人工研判用 GUI多场景进库用 Python。第 13 篇《稳态到瞬态的衔接Fathom → Impulse 互转与初始条件》进入高级阶段——跨 AFT 产品直接 Open 即转换的机制与代价不支持结点降级为 General Component/Branch、Impulse 用稳态解自动初始化瞬态、Transient Checkpoints以及转换后必须做的对象守恒复核。FAQ与第〇节一一对应Q1为什么多场景输出面板里有时看不到某些场景的数据A因为 AFT Fathom/Arrow 通常把输出存在模型文件里以减小体积显示多场景输出需要生成 .out 输出文件若还没生成例如只是加载未运行面板就可能看不到全部场景数据解决方式是用 File Start Batch Run 重跑一遍生成输出文件。Q2多场景结果收进 Excel该选单 sheet 还是多 sheetA若想把多场景放进同一工作簿只应指定一个 sheet推荐便于一次读回若指定多个 sheet 则只能每个场景导出为独立工作簿再用脚本按文件名当场景名合并。Q3几十个场景的结果怎么变成可判读的表A三个视角透视表object, unit×scenario相对基准场景的差值与百分比注意基准为 0 时的除零极值包络每对象每单位取最大最小并记录所在场景、按极差排序。Q4什么是包络它解决什么问题A包络是对全部场景按对象与参数取最大值和最小值并同时记录极值出现在哪个场景它解决管网设计要回答的所有工况里最坏情况有多坏、发生在哪只给极值不给场景在工程上没有用。Q5官方 Scenario Comparison Tool 与 Python 聚合脚本如何分工A场景少如不超过 5 个且需人工研判时用官方 Scenario Comparison Tool/Grid 并排比对场景多几十上百需要进库、出报表、画包络时用 Python 聚合也可两者结合Python 出结论表、GUI 工具做逐项复核。
返回列表