"행을 가져오는 위치"가 오래 걸리고 있습니다.각 열이 기본 데이터 테이블 열의 이름이고 행의 값이 기본 테이블의 해당 열에 잘못된 데이터가 있는 부품 번호인 참조 테이블이 있습니다.예를 들어, 기본 테이블의 열 1은 부품 번호이고 열 2는 "Temp"입니다.행 번호가 부품 번호와 같으므로 행 1이 부품 "1"이고 "Temp" 열의 값이 65라고 가정해 보겠습니다.파트 2의 온도는 -100이므로 잘못된 데이터입니다.따라서 "Temp"라는 열 아래의 참조 테이블에서 행 1의 값은 "2"입니다.이는 기본 테이블에 잘못된 데이터가 있는 모든 부품 번호에 대해 반복된 다음 각 열에 대해서도 반복됩니다.
이것이 나에게 제공하는 것은 잘못된 데이터 참조 테이블입니다. 그러면 기본 테이블에 대한 최신 데이터를 가져올 때마다 반복하여 잘못된 데이터를 자동으로 제거할 수 있습니다.그러나 작동하는 코드는 다음과 같습니다.
(여기서 vlist에는 참조 테이블의 모든 부품 번호가 포함되어 있고 dt2는 기본 데이터 테이블입니다)
try(rowindex=dt2 << Get Rows Where(contains(vlist,:WORKORDERNO )));
엄청 느립니다.완료하는 데 22초가 걸립니다.처리해야 할 열이 196개이므로 시간이 오래 걸립니다.속도를 높이는 방법에 대한 제안을 주시면 감사하겠습니다!
전체 코드는 다음과 같습니다.
names default to here(1);
dt=open("J:\Public\Ti Process Control\Dashboard Files\JMP data for CC's\Limits\master_data_table_clean_up.jmp", invisible(1)); //this is the reference table
dt<<BEGIN data="https://community.jmp.com/" update=""></BEGIN>자동화 및 스크립팅윈도우Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.JMP가 이름 확인을 수행하는 방법을 고려하십시오.당신이 실행할 때 어디에 행 가져오기() 함수를 사용하면 테이블에서 행별로 이동하여 다음을 평가합니다. 어디 표현.각 평가에는 정의된 모든 변수에 대한 이름 확인이 필요합니다. vlist vairable은 실행 루프 외부에서 정의되므로 각 반복마다 범위 탐색을 수행해야 하므로 많은 작업이 낭비됩니다.
이 문제를 해결하려면 다음과 같이 조회 전체에서 일정할 이름을 사전 평가하는 것이 좋습니다.
Names Default To Here( 1 );
dt = Open(
"J:\Public\Ti Process Control\Dashboard Files\JMP data for CC's\Limits\master_data_table_clean_up.jmp",
invisible( 1 )
); //this is the reference table
dt << begin data update;
cols = dt << get column names();
dt2 = Data Table( "Master data pull daily download" ); //this is the main table
dt2 << begin data update;
dt2 << Clear Select();
cols2 = dt2 << get column names();
vlist = {};
For( i = 1, i <= 2 /*N items(cols)*/, i++,
Try( vlist = Column( dt, cols[i] ) << get values );
starttime = Tick Seconds();
Eval( Eval Expr(
Try( rowindex = dt2 << Get Rows Where( Contains( Expr( vlist ), :WORKORDERNO ) ) );
) );
endtime = Tick Seconds();
Print( "run time", Eval Insert( "Analysis took ^round(endtime - starttime)^ seconds" ) );
Try( Column( dt2, cols[i] )[rowindex] = . );
);
dt2 << end data update;
dt << end data update;
Close( dt, nosave );주목하세요 평가( 평가 Expr( ... Expr( vlist ) ... ) ) 표현식 - 사전 평가입니다. vlist 루프 전체에서 일정하기 때문입니다.
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.AsConstant(vList)를 사용하면 동일한 효과를 얻을 수 있다고 생각합니다. 'vlist'라는 이름은 각 GetRowsWhere 호출에 대해 한 번만 평가되어야 합니다.
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.답장을 보내 주셔서 감사합니다 @ErraticAttack , 코드 수정 사항을 입력했고 코드가 22초에서 21초 만에 실행되었습니다.조금 나아졌지만 내가 있어야 할 곳은 아닙니다.다른 아이디어라도 감사하겠습니다!
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.또한 Loc을 사용하는 방법을 찾을 수 있다면 이와 같은 대부분의 상황에서 Loc을 사용하는 것이 더 빠르다는 것을 알았습니다. 이보다 더 좋은 방법이 있을 수 있지만 GetRowsWhere 호출을 대체하기 위해 이와 같은 방법을 시도해 볼 수 있습니다.
dt = New Table( "BadTable",
Add Rows( 100 ),
New Column( "BadPartNumbers",
Formula( Random Integer( 1000 ) ),
),
);
dt2 = New Table( "FullTable",
Add Rows( 10000 ),
New Column( "NewPartNumbers",
Formula( Random Integer( 1000 ) ),
),
);
newPNumbers = dt2:NewPartNumbers<< GetValues;
badPNumbers = AssociativeArray(dt:BadPartNumbers << GetValues);
rowIndex = Loc(Matrix(badPNumbers << GetValues(AsList(newPNumbers))));
귀하의 테이블이 어떻게 설정되어 있는지 정확히 모르겠지만 기본적으로 잘못된 부품 번호를 잘못된 부품 번호가 1을 반환하고 다른 모든 항목은 0을 반환하는 연관 배열로 바꾸는 것입니다. 모든 부품 번호 목록을 GetValues에 전달하면 각 행에 대해 1과 0 목록이 반환됩니다. 이에 대해 Loc를 호출하면 1이 발견된 인덱스가 반환됩니다. 이는 잘못된 부품 번호가 있는 행에 해당해야 합니다.
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.@ErraticAttack 그래서 사람들이 함께 플레이할 수 있도록 테스트 마스터 데이터 테이블과 참조 테이블을 만들어 공유할 수 있었지만 그렇게 했을 때 스크립트는 1초도 안 되어 정말 빠르게 실행되었습니다.이제 이것이 실제 데이터 테이블과 관련이 있는지 궁금합니다.
테스트 테이블은 다음과 같습니다

Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.데이터에 따라 이러한 확인을 수행하는 데 사용할 수 있는 다양한 방법이 있습니다(조인/업데이트, 위치, 행 가져오기, 연관 배열, 요약 테이블...). 테이블에는 몇 개의 행이 있습니까? 참조 테이블 열의 최대 값은 몇 개입니까? 대부분의 값이 비어 있습니까(목록을 더 작게 만들거나 목록을 한 번만 포함하려면 비교를 수행하기 전에 빈 값을 제거하십시오)?
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.여기요 @jthi ,
기본 테이블의 개요는 다음과 같습니다.

그리고 여기에 참조 테이블이 있습니다:

참조 테이블의 각 열에 포함된 데이터 양은 다음과 같습니다.(누락된 데이터 스크리너 출력에서)
번호 누락
0
0
0
0
3115
6075
12237
16591
16591
16591
16591
16772
17038
17093
17095
17095
17099
17099
17109
17110
17113
21542
22781
23634
24792
24792
25058
25172
25280
25341
25356
25376
25376
25827
25863
25875
25893
25894
25897
25905
25942
25957
25963
25963
25963
25965
25968
25968
25968
25968
26367
26564
27190
27404
27414
27420
27437
27453
27465
27474
27478
27493
27503
27522
27547
27553
27573
27592
27597
27597
27597
27597
27619
27626
27628
27628
27629
27629
27629
27629
따라서 많은 양의 잘못된 데이터가 있는 소수의 열로 인해 대부분의 열은 "누락된 데이터"/공백으로 가득 차 있습니다.
vlist에 이러한 공백이 모두 있으면 속도가 느려지는지 궁금합니다.

Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.모든 공백으로 인해 코드 속도가 느려질 것으로 생각됩니다.이에 대한 해결 방법은 다음과 같습니다.vlist 생성을 다음으로 바꾸십시오.
Try( vlist = Associative Array( As Column( cols[i] ) ) << get keys );
If( vlist[1] == "",
Remove From( vlist, 1, 1 )
);
Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.특히 목록에서 값을 찾을 수 없는 경우 속도가 느려질 가능성이 높습니다.
Names Default To Here(1);
test = {"a", "b", "c", "d", "e", "f"};
test2 = test || Repeat({""}, 27629);
lookup_val = "a";
repeats = 200;
tests = {};
For(i = 1, i <= repeats, i++,
start = HP Time();
Contains(test, lookup_val);
wait(0);
end = HP Time();
Insert Into(tests, (end-start)/1e6);
);
tests2 = {};
For(i = 1, i <= repeats, i++,
start = HP Time();
Contains(test2, lookup_val);
wait(0);
end = HP Time();
Insert Into(tests2, (end-start)/1e6);
);
Show(Mean(tests), Std Dev(tests), Mean(tests2), Std Dev(tests2));
Show(Median(tests2)/Median(tests));
편집하다:
이 두 테스트 스크립트는 모두 매우 빠르게 작성되므로 실수가 있을 수 있습니다.
Names Default To Here(1);
Random Reset(1);
dt_data = New Table("Data",
Add Rows(30000),
New Column("first", Numeric, Nominal, << Set Each Value(Row())),
New Column("second", Numeric, Nominal, << Set Each Value(Row())),
invisible
);
Column(dt_data, "first") << Set Data Type("Character");
Column(dt_data, "second") << Set Data Type("Character");
dt_lookup = New Table("Lookup",
Add Rows(5000),
New Column("first", Numeric, Nominal, Values(Random Shuffle(1::1000)[1::10])),
New Column("second", Numeric, Nominal, Values(Random Shuffle(1::1000)[1::500])),
invisible
);
Column(dt_lookup, "first") << Set Data Type("Character");
Column(dt_lookup, "second") << Set Data Type("Character");
start = HP Time();
dt_data << Get Rows Where(Contains(As Constant(dt_lookup[0, "first"]), :first));
dt_data << Get Rows Where(Contains(As Constant(dt_lookup[0, "second"]), :second));
end = HP Time();
show((end - start)/1e6);
wait(0);
start = HP Time();
dt_data << Get Rows Where(Contains(As Constant(Associative Array(dt_lookup[0, "first"]) << get keys), :first));
dt_data << Get Rows Where(Contains(As Constant(Associative Array(dt_lookup[0, "second"]) << get keys), :second));
end = HP Time();
show((end - start) / 1e6);
Close(dt_data, no save);
Close(dt_lookup, no save);
가지고 있는 값의 수와 문자인지 여부에 따라(귀하의 경우에는 문자인 것 같습니다) Associative Array() 대신 Summarize()를 사용하여 고유한 값을 얻는 것이 더 빠르지만 그렇게 크지는 않을 것입니다. 이 경우 효과의
Names Default To Here(1);
dt_lookup = New Table("Lookup",
Add Rows(5000),
New Column("test", Numeric, Nominal, Values(Random Shuffle(1::1000)[1::500])),
invisible
);
Column(dt_lookup, "test") << Set Data Type("Character");
start = HP Time();
Summarize(dt_lookup, uniq_vals = by(Column(dt_lookup, "test")));
end = HP Time();
show((end - start) / 1e6);
start = HP Time();
uniq_vals2 = Associative Array(Column(dt_lookup, "test")) << get keys;
end = HP Time();
show((end - start) / 1e6);
Show(N Items(uniq_vals), N Items(uniq_vals2));
Close(dt_lookup, no save);Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.이는 조기 최적화 범주에 속할 가능성이 높지만 JMP의 업데이트는 때때로 매우 빠를 수 있으며 여기에서는 일부 열 이름을 바꾸고 빈 값으로 가득 찬 조회 테이블에 새 열을 추가하는 데 사용될 가능성이 높습니다.
Names Default To Here(1);
dt_data = New Table("Data",
Add Rows(30000),
New Column("first", Numeric, Nominal, << Set Each Value(Row())),
New Column("second", Numeric, Nominal, << Set Each Value(Row())),
invisible
);
Column(dt_data, "first") << Set Data Type("Character");
Column(dt_data, "second") << Set Data Type("Character");
dt_lookup = New Table("Lookup",
Add Rows(5000),
New Column("first", Numeric, Nominal, Values(Random Shuffle(1::30000)[1::500])),
invisible
);
Column(dt_lookup, "first") << Set Data Type("Character");
/*
start = HP Time();
Summarize(dt_lookup, uniq_vals = by(:first));
r = dt_data << Get Rows Where(Contains(As Constant(uniq_vals), :first));
dt_data[r, "second"] = "";
end = HP Time();
Show((end-start)/1e6);
*/
missing_col = dt_lookup << New Column("missing_vals", Numeric, Nominal);
start = HP Time();
i = 1;
Column(dt_lookup, "first") << Set Name(Char(i));
missing_col << Set Name("second");
dt_data << Update(With(dt_lookup), Match Columns(:first = Eval(Char(i))), Replace Columns in Main Table(:second));
end = HP Time();
Show((end-start)/1e6);
Close(dt_data, no save);
Close(dt_lookup, no save);Re: "행을 가져오는 위치"가 오래 걸리고 있습니다.잘 작동했습니다. 감사합니다!
덕분에 @jthi 또한!txnelson 코드의 복사 및 붙여넣기가 완벽하게 작동했기 때문에 그가 위에 게시한 그의 코드를 자세히 살펴보지는 않았지만 시간을 내어 코드를 작성해 주셔서 감사합니다.