回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法有很多选项可以做到这一点(尤其是使用脚本)。您可以使用表菜单下的 JMP 查询生成器(您可以使用数据表)构建 SQL 查询,您可以在其中定义范围和行的连接方式。
回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法?这是我的方法。如果数据是经过排序的,那么可以将它们传一遍,就可以找到需要的值。请查看下面的 JSL,了解可采用的一般方法。代码未经测试,我没有数据表来测试它。但是,我以前多次使用过这种方法,这是一种有效的方法。但要准备好稍微调整一下。
Names Default To Here( 1 );
dt = Current Data Table();
nr = N Rows( dt );
dtPDTag = Data Table( "2205 - 2209 PD3102" );
nrPD = N Rows( dtPDTag );
// Sort both data tables by the timestamps to allow the tables to only
// have to be read once
// Before sorting the data, if the tables need to be returned to the
// original order then create a new column in each table that represents
// the current Row number, which then will allow the table to be sorted
// back to the original order
// dt << New Column( "_row_", set each value( Row() ));
// dtPDTag << New Column( "_row_", set each value( Row() ));
dt << sort( By( :StartTime, :EndTime ), order( ascending, ascending ), replace table( 1 ) );
dtPDTag << sort( By( :DateTime ), order( ascending ), replace table( 1 ) );
PDStart = 1; // Variable that keeps track of where in the dtPDTag table to start to find values
For( dtI = 1, dtI <= nr, dtI++,
For( dtPDI = PDStart, dtPDI <= nrPD, dtPDI++,
If( ( dtPDTag:DateTime[dtPDI] > dt:StartTime[dtI] ) & ( dtPDTag:DateTime[dtPDI] < dt:EndTime ),
dtPDTag:PO[dtPDI] = dt:PO[dtI];
dtPDTag:Symbol[dtPDI] = dt:Symbol[dtI];
PDStart = dtPDI;
Break();
)
);
// Resort to original if required and delete the _row_ column
// dt << sort( By( _row_ ), order( ascending ), replace table( 1 ) );
// dt << delete columns( :_row_ );
// dtPDTag << sort( By( _row_ ), order( ascending ), replace table( 1 ) );
// dtPDTag << delete columns( :_row_ );
回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法?谢谢吉姆。 检查解释与我不太有效的代码:
- 您引入 PDStart 作为计数器,以避免一次又一次地遍历已经响应的行
- 你包括 Break();尽快离开循环
简而言之,通过这两项添加,您消除了我的代码固有的冗余?
回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法?正确的!
回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法?你好,
我意识到我来晚了。 我决定响应,因为我在 semi 工作时也有类似的需求,而且我的数据表非常大,以至于即使是带有 break 的单个循环对我来说也不起作用。 如果您的表那么大,请查看以下内容是否适合您。 这是我必须做的。 在常见情况下,当您在单个流程步骤中有多个时间戳时,它会节省很多时间。 这有两个原因:首先,没有比较。 其次,它只为每个流程步骤迭代一次,将表格行批量设置为值。 它通过将食谱时间戳数据直接连接到原始表上,将两者一起使用,然后删除食谱数据来实现这一点。
Names Default To Here( 1 );
//sample data table
dt1 = As Table( (1 :: 30)` || J( 30, 1, Random Uniform() ), <<COLUMN names=""></COLUMN>
如果你碰巧看到这个,让我知道它是怎么回事。
干杯,
布雷迪
回复:通过匹配两个数据表中的时间戳向行添加信息的最有效方法?嗨布雷迪,非常感谢代码。
代码遗漏了一个部分来完成这项工作。 它从运行开始就分配正确的 PO 编号和配方 ID,但是当 PO 结束时它不会停止……这意味着配方 ID 和 PO 继续排成行,直到下一个 PO 开始,因此一种“超车”。
我的数据表中有数千行,但假设从一个 PO 开始到下一个 PO 有 10 个时间段,但第一个 PO 从时间段 1 到 7,我希望时间段 8 和 9 是“ empty”,因此被删除,因为当时没有生产,然后从时间段 10 继续下一个 PO。
希望解释是有道理的。
通过匹配两个数据表中的时间戳来向行添加信息的最有效方法?我在很长一段时间内以 5 秒的间隔提取 Historian 数据,最终得到一个包含许多行的数据表。 最初,在此数据表中,我有两列(将此表称为“2205 - 2209 PD3102”,我将其称为 dtPDTag):
1. 日期/时间戳
2. 数据值(对于Historian标签)
在不同的数据表(下面的 JSL 语法中的 dt)中,我有生产的开始和结束时间,我有 PO 标识符和配方符号。 (所以四列:1. 开始日期/时间,2. 结束日期/时间,3. 采购订单号,4。 食谱符号。)
在 dtPDTag 中,我添加了两列 - PO 和符号 - 我想在其中添加 PO 编号和配方符号(基于日期/时间戳)。下面是我用来完成此任务的 JSL 代码,但我认为这是管理此任务的一种非常低效的方法。(我的计算机似乎对对其提出的要求的反应不太健康!)很高兴听到将来有更好/更有效的方法来完成此类任务。
我所说的“最有效”是指一种比下面我的 JSL 中看到的两个 for 循环和一个“if”条件的组合更有效的脚本编写方法。
Names Default To Here(1);
dt = Current Data Table();
nr = N Rows(dt); // show(nr);
lstPO = dt:PO << Get Values;
lstSymbol = dt:Symbol << Get Values;
lstStartTime = dt:StartTime << Get Values;
lstEndTime = dt:EndTime << Get Values; // show(lstPO,lstSymbol,lstStartTime,lstEndTime);
dtPDTag = data Table( "2205 - 2209 PD3102" );
nrPD = N Rows(dtPDTag); // show(nrPD);
For(j=1,j<=nr,j++,
_start = lstStartTime[j]; _end = lstEndTime[j]; // show(_start,_end);
_PO =lstPO[j]; _symbol = lstSymbol[j];
For(i=1,i<=nrPD,i++,
If( ( dtPDTag:DateTime[i] > lstStartTime[j] ) & ( dtPDTag:DateTime[i] < lstEndTime[j] ),
dtPDTag:PO[i] = lstPO[j];
dtPDTag:Symbol[i] = lstSymbol[j];
,
);
);
);
自动化和脚本编写大规模定制