특정 조건과 관련된 중복 측정을 삭제하는 스크립트 문제테이블 분할 기능을 수행하기 전에 트리밍하는 일련의 개별 측정의 여러 행으로 구성된 데이터 테이블이 있습니다. 그러나 제거하고 싶은 일부 중복 측정에 문제가 있지만 현재 코드는 내가 사용하는 것은 매우 느리고 필요한 것에 비해 비효율적일 가능성이 높습니다.
배경 정보:
- 각 행은 연속적으로 수행된 재료에 대한 개별 자동 측정의 결과이며 다음 열이 포함된 보고서를 생성합니다.
- 각 개별 재료에 할당된 고유한 부품 ID [ PartID ]
- 개별 재료 조각을 생성하는 데 사용된 원자재와 연관된 로트 ID [ LotID ]
- 수행된 측정에 대한 실제 측정값 [ 값 ]
- 측정값에 따라 측정결과 부여(Pass/Fail/Rework) [ 결과 ]
- 측정 타임스탬프 [ 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: 특정 조건과 관련된 중복 측정을 삭제하는 스크립트에 문제가 있습니다.다음은 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시간 동안 실행 상태로 두었고 여전히 실행 중인 것처럼 보였지만 프로세스가 응답하지 않았으며 궁극적으로 작업 관리자를 통해 "작업 종료"해야 했습니다). - 개선 방법에 대한 조언이 있나요?10,000개 행에 대해 실행하는 데는 10초 미만이 걸렸으므로 160만 행의 경우 선형으로 확장하면 30분 정도 걸릴 것으로 예상되지만 그렇지 않은 것 같습니다.
데이터 테이블에 저장된 제안된 스크립트 개선 사항을 참조하기 위해 데이터 테이블의 삭제된 하위 집합을 업로드하고 있습니다.정리된 테이블에는 단일 LotID만 있었지만 이는 일반적인 경우가 아니며 단지 업로드할 파일의 전체 크기를 최소화하기 위한 것입니다.
테이블에 대해 실행하려는 스크립트의 현재 버전은 다음과 같습니다.
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 );
다시 한 번, 도움을 주셔서 정말 감사드립니다!
Re: 특정 조건과 관련된 중복 측정을 삭제하는 스크립트에 문제가 있습니다.안녕하세요, 감사합니다!
지금 내 데이터 테이블에 대해 스크립트를 실행하고 있습니다. 행이 삭제된 것으로 간주되는 테이블의 행을 반복하는 것은 확실히 옳았다고 생각합니다. 이는 아마도 루프 논리를 망칠 수 있습니다.
지금 내 데이터 테이블에 대해 코드를 실행하고 있으며 다시 보고하겠습니다.또한 이 게시물에 포함할 수 있도록 데이터 테이블의 일부 조각을 정리할 수 있는지 알아보겠습니다.도움을 주셔서 정말 감사합니다!
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 );
작업할 샘플 데이터 테이블이 없었기 때문에 코드는 테스트되지 않았지만 이 접근 방식을 사용하면 모든 문제를 수정하고 작동할 수 있습니다.