여러 목록 항목을 함께 연결JMP12.2 사용 - 목록에 동일한 수의 항목이 있다고 가정하고 1대 1 방식으로 서로 다른 두 목록의 목록 항목을 함께 연결하는 빠른 방법을 찾고 있습니다. 이는 매우 큰 테이블의 각 행에 사용되므로 가능하면 반복 기능을 선호하지 않습니다.
내가 달성하고 싶은 것의 예는 다음과 같습니다.
list1 = {"a","b","c","d","e","f","g"};
list2 = {"1","2","3","4","5","6","7"};
허용되는 결과는 문자열 또는 목록일 수 있습니다. 문자열이 구분 기호로 구분된 경우.
목록 결과: {"a,1","b,2","c,3","d,4","e,5","f,6","g,7"};
문자열 결과: "a:1,b:2,c:3,d:4,e:5,f:6,g:7";
대량 맞춤화Re: 여러 목록 항목을 함께 연결합니다.내가 그걸 엉망으로 만들었어! 다음은 이전 버전의 JMP에서 제대로 작동할 수 있는 업데이트된 버전입니다.
dtGraph = New Table( "stats",
Add Rows( 0 ),
New Column( "size", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "table time", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "loop time", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) )
);
For( n = 1, n < 1e7, n *= 2,
dtGraph << addrows( 1 );
dtGraph:size[N Rows( dtGraph )] = n * 3;// 3 items repeated...
list1 = Repeat( {"a", "b", "c"}, n );
list2 = Repeat( {"1", "2", "3"}, n );
start = HP Time(); // data table method begins here
dt = New Table( "temp",
New Column( "a", Character, "Nominal", Set Values( list1 ) ),
New Column( "b", Character, "Nominal", Set Values( list2 ) ),
New Column( "c", Character, "Nominal", formula( a || ":" || b ) ),
invisible
);
dt << runformulas;
result = dt:c << getvalues;
Close( dt, nosave );
stop = HP Time(); // data table method ends here
Show( stop - start );
result = Concat Items( result, "," );
Show( Length( result ), Left( result, 100 ) );
dtGraph:table time[N Rows( dtGraph )] = (stop - start) / 1e6;
result = {};
start = HP Time(); // loop method begins here
While(
aa = Remove From( list1, 1 );
bb = Remove From( list2, 1 );
N Items( aa ); // as long as something was removed...
, // do this...
Insert Into( result, aa[1] || ":" || bb[1], 1 ) // <<<<<<<<< here
);
result=reverse(result); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< and here
stop = HP Time(); // loop method ends here
Show( stop - start );
result = Concat Items( result, "," );
Show( Length( result ), Left( result, 100 ) );
dtGraph:loop time[N Rows( dtGraph )] = (stop - start) / 1e6;
Wait( 1 );
);
dtGraph << Graph Builder(
Size( 1200, 500 ),
Show Control Panel( 0 ),
Variables( X( :size ), Y( :table time ), Y( :loop time, Position( 1 ) ) ),
Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 5 ) ), Smoother( X, Y( 1 ), Y( 2 ), Legend( 6 ) ) ),
SendToReport(
Dispatch( {}, "size", ScaleBox, {Scale( "Log" ), Inc( 1 ), Minor Ticks( 1 )} ),
Dispatch( {}, "table time", ScaleBox, {Scale( "Log" ), Format( "Best", 12 ), Inc( 1 ), Minor Ticks( 1 )} )
)
);보다 빠른 목록 설명을 위해; RemoveFrom 함수에만 집중하고 Insert Into 함수는 잊어버렸습니다.
Insert Into needs a 3rd argument to insert at the beginning of the list, and then a reverse when done.Insert Into needs a 3rd argument to insert at the beginning of the list, and then a reverse when done.Insert Into에는 목록의 시작 부분에 삽입하려면 세 번째 인수가 필요하고, 완료되면 그 반대의 인수가 필요합니다.
또한 루프의 변수 이름을 변경하여 데이터 테이블 열을 임시로 사용하지 않도록 했습니다.
Re: 여러 목록 항목을 함께 연결합니다.내 문제가 해결되었습니다. 이는 귀하와 이 문제가 유용하다고 생각하는 다른 사람들을 위한 참고 사항입니다.
JMP14.3에 액세스할 수 있지만 조직 내 호환성을 위해서는 스크립트를 JMP12.2에서 실행해야 합니다.
귀하의 분석을 시도한 결과 JMP14.3에서는 귀하와 비슷한 결과를 얻었습니다. 아마도 컴퓨팅 성능에 약간의 차이가 있을 것입니다.

그러나 JMP12.2에서는 루프 성능이 완전히 벗어났습니다. 시간이 기하급수적으로 증가하고 24번째 행에 도달하지 못했기 때문에 98304 이후에는 JMP.exe 프로세스를 종료해야 합니다.

Re: 여러 목록 항목을 함께 연결합니다.감사합니다. 잘 작동합니다. 반복 함수를 사용하더라도 성능이 좋습니다.
Re: 여러 목록 항목을 함께 연결합니다.예, 반복(각 행에 대해) 내의 반복(for)이 스크립트 성능에 심각한 영향을 미칠 것이라고 가정했을 수 있지만 예제를 구축한 후에는 @SDF1 성능이 놀라울 정도로 좋다고 제안했습니다.
비교해 주셔서 감사합니다. 저는 C++가 항상 더 빠르다고 가정했지만 테이블이 항상 더 많은 오버헤드를 갖는다는 것이 이해가 됩니다. "데이터 업데이트 시작" 및/또는 "개인" 테이블이 테이블 오버헤드를 개선할 수 있을지 궁금합니다.
Re: 여러 목록 항목을 함께 연결합니다.JSL 루프는 당연히 나쁜 평판을 가지고 있습니다. 루프 내부가 많은 작업을 수행하는 경우 루프의 오버헤드는 일반적으로 별로 중요하지 않습니다. 그리고 JSL 루프가 없는 솔루션은 다른 곳, 아마도 C++에서 약간 더 빠르지만 여전히 루프를 포함하게 됩니다. 어쨌든, 다음은 두 가지 방법을 비교한 것입니다. 하나는 JSL 루프를 사용하는 것이고 다른 하나는 JMP의 C++ 코드에 숨겨진 루프를 사용하는 것입니다.
Graph showing crossover times of the two algorithms at around 39,000 elements.Graph showing crossover times of the two algorithms at around 39,000 elements.약 39,000개 요소에서 두 알고리즘의 교차 시간을 보여주는 그래프.
dtGraph = New Table( "stats",
Add Rows( 0 ),
New Column( "size", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "table time", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) ),
New Column( "loop time", Numeric, "Continuous", Format( "Best", 12 ), Set Values( [] ) )
);
For( n = 1, n < 1e7, n *= 2,
dtGraph << addrows( 1 );
dtGraph:size[N Rows( dtGraph )] = n * 3;// 3 items repeated...
list1 = Repeat( {"a", "b", "c"}, n );
list2 = Repeat( {"1", "2", "3"}, n );
start = HP Time(); // data table method begins here
dt = New Table( "temp",
New Column( "a", Character, "Nominal", Set Values( list1 ) ),
New Column( "b", Character, "Nominal", Set Values( list2 ) ),
New Column( "c", Character, "Nominal", formula( a || ":" || b ) ),
invisible
);
dt << runformulas;
result = dt:c << getvalues;
Close( dt, nosave );
stop = HP Time(); // data table method ends here
Show( stop - start );
result = Concat Items( result, "," );
Show( Length( result ), Left( result, 100 ) );
dtGraph:table time[N Rows( dtGraph )] = (stop - start) / 1e6;
result = {};
start = HP Time(); // loop method begins here
While(
a = Remove From( list1, 1 );
b = Remove From( list2, 1 );
N Items( a ); // as long as something was removed...
, // do this...
Insert Into( result, a[1] || ":" || b[1] )
);
stop = HP Time(); // loop method ends here
Show( stop - start );
result = Concat Items( result, "," );
Show( Length( result ), Left( result, 100 ) );
dtGraph:loop time[N Rows( dtGraph )] = (stop - start) / 1e6;
Wait( 1 );
);
dtGraph << Graph Builder(
Size( 1200, 500 ),
Show Control Panel( 0 ),
Variables( X( :size ), Y( :table time ), Y( :loop time, Position( 1 ) ) ),
Elements( Points( X, Y( 1 ), Y( 2 ), Legend( 5 ) ), Smoother( X, Y( 1 ), Y( 2 ), Legend( 6 ) ) ),
SendToReport(
Dispatch( {}, "size", ScaleBox, {Scale( "Log" ), Inc( 1 ), Minor Ticks( 1 )} ),
Dispatch( {}, "table time", ScaleBox, {Scale( "Log" ), Format( "Best", 12 ), Inc( 1 ), Minor Ticks( 1 )} )
)
);JMP 14는 제가 액세스할 수 있는 가장 오래된 버전입니다. 루프 알고리즘은 JMP 12에서도 비슷한 성능을 발휘할 것으로 생각됩니다. 이전 JMP 버전은 목록에서 빠른 인덱싱을 지원하지 않았지만 첫 번째 요소를 제거하는 것은 빠르기 때문에 두 목록을 처리하면서 의도적으로 두 목록을 삭제합니다. 데이터 테이블 알고리즘은 루프의 첫 번째이므로 목록이 삭제되기 전에 목록을 사용할 수 있습니다.
JSL을 되돌아보면 알고리즘이 더 간단하거나 따르기 쉽다고 주장해서는 안 됩니다.
Re: 여러 목록 항목을 함께 연결합니다.안녕 @ts2 ,
결과로 무엇을 하려는지에 따라 몇 가지 다른 방법으로 접근할 수 있습니다. 반복 함수를 수행하고 싶지 않다는 것은 알지만 한 목록의 요소가 다른 목록의 요소에 연결된 올바른 출력을 얻으려면 For 루프를 수행해야 한다고 생각합니다. 연관 배열을 수행하는 것도 고려해 볼 수 있습니다.
다음은 솔루션을 시작하는 데 도움이 될 수 있는 일부 JSL입니다.
names default to here(1);
list1 = {"a","b","c","d","e","f","g"};
list2 = {"1","2","3","4","5","6","7"};
AA = Associative Array(List1, List2);
i=.;
result1={};
For(i=1, i<=nitems(list1), i++,
result1[i]=list1[i]||":"||list2[i]
);
result 2 = EvalList({Concat Items(result1, ", ")});
Show(result1);
Show(result2);
Show (AA);도움이 되었기를 바랍니다!,
DS