Concaténer plusieurs éléments de liste ensembleUtilisation de JMP12.2 - Je recherche un moyen rapide de concaténer des éléments de liste à partir de deux listes différentes de manière 1 à 1 - en supposant que les listes contiennent le même nombre d'éléments. Ceci sera utilisé pour chaque ligne dans de très grands tableaux - je préfère donc aucune fonction itérative si possible.
Voici un exemple de ce que je souhaite réaliser :
liste1 = {"a", "b", "c", "d", "e", "f", "g"};
liste2 = {"1", "2", "3", "4", "5", "6", "7"} ;
Le résultat acceptable peut être une chaîne ou une liste. Si chaîne séparée par des délimiteurs.
Résultat de la liste : {"a,1", "b,2", "c,3", "d,4", "e,5", "f,6", "g,7"} ;
Résultat de la chaîne : "a:1,b:2,c:3,d:4,e:5,f:6,g:7" ;
Personnalisation de masseRe : Concaténer plusieurs éléments de liste ensembleJ'ai fait un gâchis avec ça ! Voici une version mise à jour qui fonctionnera probablement correctement dans les anciennes versions de 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 )} )
)
);voir Liste rapide pour une explication; Je me concentrais sur la fonction RemoveFrom et j'oubliais la fonction 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 a besoin d'un 3ème argument à insérer au début de la liste, puis d'un reverse une fois terminé.
J'ai également renommé les variables de la boucle afin qu'elles n'utilisent pas les colonnes du tableau de données comme temporaires.
Re : Concaténer plusieurs éléments de liste ensembleMon problème est résolu - c'est plutôt une information pour vous et pour ceux qui pourraient le trouver utile.
J'ai accès à JMP14.3 mais le script doit s'exécuter sur JMP12.2 pour des raisons de compatibilité au sein de mon organisation.
J'ai essayé votre analyse et pour JMP14.3, j'ai obtenu des résultats similaires à ceux de vous - probablement quelques différences de puissance de calcul.

Cependant, avec JMP12.2, les performances de la boucle sont complètement hors de propos. Je dois tuer le processus JMP.exe après 98304 car le temps augmentait de façon exponentielle et n'aurait jamais atteint la 24ème ligne :

Re : Concaténer plusieurs éléments de liste ensembleMerci cela fonctionne très bien. Même s’il utilise une fonction itérative, il offre de bonnes performances.
Re : Concaténer plusieurs éléments de liste ensembleOui, j'ai peut-être supposé que l'itération (pour) dans l'itération (pour chaque ligne) aurait un impact important sur les performances du script, mais après avoir construit l'exemple @SDF1 suggéré que la performance est étonnamment bonne.
Merci pour la comparaison - j'aurais supposé que le C++ serait toujours plus rapide, mais il est logique qu'une table ait toujours plus de surcharge. Je me demande si la table « Commencer la mise à jour des données » et/ou « Privée » améliorerait la surcharge de la table ?
Re : Concaténer plusieurs éléments de liste ensembleLes boucles JSL ont une mauvaise réputation à juste titre. Si les entrailles de la boucle font beaucoup de travail, la surcharge de la boucle n'aura généralement pas beaucoup d'importance. Et toute solution sans boucle JSL impliquera une boucle ailleurs, peut-être en C++ qui sera un peu plus rapide, mais quand même. Quoi qu'il en soit, voici une comparaison de deux méthodes, l'une impliquant une boucle JSL et l'autre utilisant une boucle cachée dans le code C++ de JMP.
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.Graphique montrant les temps de croisement des deux algorithmes à environ 39 000 éléments.
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 est le plus ancien auquel j'ai accès. Je pense que l'algorithme de boucle aura des performances similaires dans JMP 12. Il détruit intentionnellement les deux listes au fur et à mesure qu'il les traite, car les anciennes versions de JMP n'avaient pas d'indexation rapide dans les listes, mais la suppression du premier élément est rapide. L'algorithme de la table de données est le premier dans la boucle et peut donc utiliser les listes avant qu'elles ne soient détruites.
En regardant le JSL, je ne devrais pas prétendre que l'un ou l'autre des algorithmes est plus simple ou plus facile à suivre.
Re : Concaténer plusieurs éléments de liste ensembleSalut @ts2 ,
En fonction de ce que vous souhaitez faire avec les résultats, vous pouvez l'aborder de différentes manières. Je sais que vous ne voulez pas faire de fonctions itératives, mais pour obtenir le bon résultat où les éléments d'une liste sont connectés aux éléments d'une autre liste, je pense que vous devez faire une boucle For. Vous pouvez également envisager de créer un tableau associatif.
Vous trouverez ci-dessous quelques JSL qui pourraient vous aider à démarrer sur une solution.
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);J'espère que cela t'aides!,
DS