Mehrere Listenelemente zusammenfassenMit JMP12.2 suche ich nach einer schnellen Möglichkeit, Listenelemente aus zwei verschiedenen Listen 1:1 zusammenzuführen – vorausgesetzt, die Listen enthalten die gleiche Anzahl von Elementen. Dies wird für jede Zeile in sehr großen Tabellen verwendet – daher bevorzuge ich, wenn möglich, keine iterative Funktion.
Hier ist ein Beispiel dafür, was ich erreichen möchte:
list1 = {"a", "b", "c", "d", "e", "f", "g"};
list2 = {"1", "2", "3", "4", "5", "6", "7"};
Ein akzeptables Ergebnis kann eine Zeichenfolge oder eine Liste sein. Wenn die Zeichenfolge durch Trennzeichen getrennt ist.
Listenergebnis: {"a,1", "b,2", "c,3", "d,4", "e,5", "f,6", "g,7"};
String-Ergebnis: „a:1,b:2,c:3,d:4,e:5,f:6,g:7“;
MassenanpassungBetreff: Mehrere Listenelemente zusammenfassenDas habe ich vermasselt! Hier ist eine aktualisierte Version, die wahrscheinlich in älteren JMP-Versionen korrekt funktionieren wird:
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 )} )
)
);sehen Schnelle Liste für eine Erklärung; Ich habe mich auf die RemoveFrom-Funktion konzentriert und die Insert Into-Funktion vergessen.
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.„Einfügen in“ erfordert ein drittes Argument, das am Anfang der Liste eingefügt wird, und anschließend ein umgekehrtes Argument, wenn es fertig ist.
Außerdem habe ich die Variablen in der Schleife umbenannt, damit sie die Datentabellenspalten nicht als temporäre Variablen verwenden.
Betreff: Mehrere Listenelemente zusammenfassenMein Problem ist gelöst – dies dient eher Ihrer Information für Sie und andere, die es möglicherweise nützlich finden.
Ich habe Zugriff auf JMP14.3, aber das Skript muss aus Gründen der Kompatibilität innerhalb meiner Organisation auf JMP12.2 ausgeführt werden.
Ich habe Ihre Analyse ausprobiert und für JMP14.3 ähnliche Ergebnisse wie Sie erhalten – wahrscheinlich einige Unterschiede in der Rechenleistung.

Allerdings gerät die Leistung der Schleife mit JMP12.2 völlig aus dem Rahmen. Ich muss den JMP.exe-Prozess nach 98304 beenden, da die Zeit exponentiell zunahm und nie die 24. Zeile erreicht hätte:

Betreff: Mehrere Listenelemente zusammenfassenVielen Dank, das funktioniert großartig. Obwohl es eine iterative Funktion verwendet, weist es eine gute Leistung auf.
Betreff: Mehrere Listenelemente zusammenfassenJa, ich bin vielleicht davon ausgegangen, dass die Iteration (für) innerhalb der Iteration (für jede Zeile) die Skriptleistung erheblich beeinträchtigen würde, aber nachdem ich das Beispiel erstellt habe @SDF1 schlug vor, dass die Leistung überraschend gut ist.
Vielen Dank für den Vergleich – ich hätte angenommen, dass C++ immer schneller ist, aber es macht Sinn, dass eine Tabelle immer mehr Overhead hat. Ich frage mich, ob die Tabellen „Datenaktualisierung beginnen“ und/oder „Privat“ den Tabellenaufwand verbessern würden.
Betreff: Mehrere Listenelemente zusammenfassenJSL-Schleifen haben zu Unrecht einen schlechten Ruf. Wenn die Kerne der Schleife viel Arbeit leisten, wird der Overhead der Schleife normalerweise keine große Rolle spielen. Und jede Lösung ohne JSL-Schleife erfordert eine Schleife an einer anderen Stelle, vielleicht in C++, was zwar etwas schneller ist, aber trotzdem. Wie auch immer, hier ist ein Vergleich zweier Methoden, eine mit einer JSL-Schleife und eine mit einer Schleife, die im C++-Code von JMP versteckt ist.
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.Diagramm, das die Kreuzungszeiten der beiden Algorithmen bei etwa 39.000 Elementen zeigt.
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 ist das älteste, auf das ich Zugriff habe. Ich denke, dass der Schleifenalgorithmus in JMP 12 eine ähnliche Leistung haben wird. Es zerstört absichtlich die beiden Listen, während es sie verarbeitet, da ältere JMP-Versionen keine schnelle Indizierung in Listen hatten, aber das Entfernen des ersten Elements geht schnell. Der Datentabellenalgorithmus befindet sich als erster in der Schleife, sodass er die Listen verwenden kann, bevor sie zerstört werden.
Wenn ich auf die JSL zurückblicke, sollte ich nicht behaupten, dass einer der Algorithmen einfacher oder leichter zu befolgen ist.
Betreff: Mehrere Listenelemente zusammenfassenHallo @ts2 ,
Je nachdem, was Sie mit den Ergebnissen machen möchten, können Sie auf unterschiedliche Weise an die Sache herangehen. Ich weiß, dass Sie keine iterativen Funktionen ausführen möchten, aber um die richtige Ausgabe zu erhalten, bei der die Elemente einer Liste mit den Elementen einer anderen Liste verbunden sind, müssen Sie meiner Meinung nach eine For-Schleife ausführen. Sie können auch ein assoziatives Array erstellen.
Nachfolgend finden Sie einige JSLs, die Ihnen beim Einstieg in eine Lösung helfen können.
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);Hoffe das hilft!,
DS