特定の条件に固有の冗長な測定を削除するスクリプトの問題テーブル分割機能を実行する前にトリミングしている一連の個々の測定値の複数の行で構成されるデータテーブルがありますが、削除したい冗長な測定値に問題がありますが、現在のコードは使用しているのは非常に遅く、必要なものに対して非効率的である可能性があります。
背景情報:
- 各行は、連続して実行された材料片の個々の自動測定の結果であり、次の列を含むレポートを生成します。
- 個々の素材に割り当てられた一意のパーツ ID [ PartID ]
- 個々の材料を作成するために使用される原材料に関連付けられたロット ID [ LotID ]
- 実施した測定の実測値 [ Value ]
- 測定値に基づいて割り当てられた測定結果 (Pass/Fail/Rework) [ Result ]
- 測定タイムスタンプ [ Date_Created ]
私の機器は、材料ごとに数十行の測定値を生成し、レポートごとに数千の材料を処理します。これらのレポートは、元のデータ テーブルとして JMP に送られます。各レポートには複数のロットも含まれているため、データ テーブルには "PartID = 1" への複数の参照があります。これは、各ロットに 1 から始まる連番が与えられているためです。そのため、特定の材料を参照するには PartID と LotID の両方を使用する必要があります。結果が「再加工」の場合、測定機器はその個々の材料片のそれ以上の測定を停止し、材料片の向きを変えてラインの最初に戻し、以前のすべてのテストを再測定します。マテリアルに関連付けられた同じ固有のパーツ ID を保持します。
望ましい結果:
スクリプトを使用してデータ テーブルを調べ、リワーク結果までのすべての測定値を削除したいと考えています。これを行うために、現在JSLスクリプトを使用して各行をループし、次のことを行っています。
- 結果が「やり直し」かどうかを識別します。その場合は、次の手順を実行します。
- 指定されたマテリアルの PartID を「xPartID」として識別します
- 特定の素材の LotID を「xLot」として識別します
- 指定された測定の Date_Created を「xDate」として識別します
- (PartID = xPartID) および (LotID = xLot) および (Date_Created <= xDate) であるすべての行を選択して削除します。
- 結果が「やり直し」でない場合は、ループから抜け出し、続行する必要はありません。
私は極端なスローダウンを続けており、基本的にコードがプログラムのクラッシュにつながります。ステップバイステップで実行するとうまくいくように見えますが、そのままにしておくと最終的に死んでしまいます。 実際のコードは次のとおりです。
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value(
_rcOrig,
{"FailOnHighRework", "aRework",
"FailOnLowRework", "aRework"},
Unmatched( _rcNow )
)},
Update Properties( 1 ),
Target Column( :result )
);
//Sorting the table using the result column after the recode, so all of the rework rows are at the start of the table
SortColumn = "result";
dt << Sort( By( :result ), Replace Table, Order( Ascending ), Suppress formula evaluation( 1 ) );
//now run the row-by-row script
dt << begin data update;
for each row(
If( :result == "aRework",
xRow = Row();
xPartID=:PartID[Row()];
xLot=:lot[Row()];
xDate=:date_created[Row()];
dt <<SELECT where=""></SELECT>私は JMP 16.2.0 (570548) を使用しています。
スクリプティングRe: 特定の条件に固有の冗長な測定を削除するスクリプトの問題For Each Row を使用してデータ テーブルをループし、行を削除してループしているテーブルを変更し続け、ループが混乱しているという問題が発生していると思います。
これは、問題を解消し、かなり効率的に実行できると思われる未テストのコードです。
Names Default To Here( 1 );
//Recoding the two potential "Rework" results into a shared value "aRework"; putting the letter "a" in front of it so if I sort by the column ascending then all of these values are at the start of the list, to hopefully make it easier and faster to process them.
dt << Recode Column(
dt:result,
{Map Value( _rcOrig, {"FailOnHighRework", "aRework", "FailOnLowRework", "aRework"}, Unmatched( _rcNow ) )},
Update Properties( 1 ),
Target Column( :result )
);
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
For( i = 1, i <= N Rows( dt2 ), i++,
dt << select where(
(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected ) > 0,
dt << delete rows
);
)
);
close( dt2, nosave );
使用するサンプル データ テーブルがなかったので、コードはテストされていませんが、このアプローチにより、問題を修正して動作させることができるはずです。
Re: 特定の条件に固有の冗長な測定を削除するスクリプトの問題こんにちは、そしてありがとう!
現在、データ テーブルに対してスクリプトを実行しています。行が削除されたと積極的に考えられているテーブルの行を反復処理することは間違いなく正しかったと思います。これはおそらくループロジックをいじっていました。
現在、データ テーブルに対してコードを実行しており、報告します。また、この投稿に含めることができるように、データ テーブルのスニペットをサニタイズできるかどうかも確認します。ご協力ありがとうございました!
Re: 特定の条件に固有の冗長な測定を削除するスクリプトの問題これは、dt の 100 行ごとに処理された後に出力されるスクリプトのバージョンです。
dt = Current Data Table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
//dt << begin data update;
start = 1;
end = 0;
alldt2 = N Rows( dt2 );
While( N Rows( dt2 ) > 100,
TotalRows = N Rows( dt2 );
If( TotalRows > 100,
TotalRows = 100
);
end = end + TotalRows;
For( i = 1, i <= TotalRows, i += 1,
dt << select where(
dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2
:Date_created[i]
);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
//dt << end data update;
dt2 << delete rows( 1 :: 100 );
Show(
"Rows " || Char( start ) || " to " || Char( end ) || " of " || Char( alldt2 ) ||
" processed"
);
);
Close( dt2, nosave );
x 行数を処理するように設定してから、再実行してさらに多くの行を処理することもできます。
Re: 特定の条件に固有の冗長な測定を削除するスクリプトの問題こんにちは、
スクリプトは意図したとおりに機能しているように見え、非常に小さなデータセット (合計 10,000 行) に対して実行すると、うまく高速に見えますが、実際に作業しているデータセット (160 万行) では速度が大幅に低下しています。 )プログラムを強制終了しているかどうかはわかりません(応答せず、約1.5時間実行したままにして、まだ実行しているように見えましたが、プロセスは応答せず、最終的にタスクマネージャーを介して「タスクを終了」する必要がありました) - 改善方法について何かアドバイスはありますか?10k 行に対して実行するのにおそらく 10 秒未満しかかからなかったので、160 万の場合、線形にスケーリングすると 30 分かかることを願っていますが、そうではないようです。
データ テーブルに保存された提案されたスクリプトの改善を参照するために、サニタイズされたデータ テーブルのサブセットをアップロードしています。サニタイズされたテーブルには LotID が 1 つしかありませんでしたが、通常はそうではなく、アップロードするファイルの合計サイズを最小限に抑えるためです。
テーブルに対して実行しようとしているスクリプトの現在のバージョンは次のとおりです。
dt = current data table();
dt << select where( :result == "aRework" );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ) );
// Remove aRework rows from original table
dt << delete rows;
// Loop across the aRework table and delete rows in orininal table
dt << begin data update;
TotalRows=N Rows(dt2);
For( i = 1, i <= N Rows( dt2 ), i+=1,
dt << select where(dt:partid == dt2:PartID[i] & dt:lot == dt2:Lot[i] & dt:date_created <= dt2:Date_created[i]);
If( N Rows( dt << get selected rows ) > 0,
dt << delete rows
);
);
dt << end data update;
close( dt2, nosave );
もう一度、助けてくれてありがとう!