Concatenar varios elementos de la lista juntosUso de JMP12.2: estoy buscando una forma rápida de combinar elementos de lista de dos listas diferentes de 1 a 1, suponiendo que las listas tengan la misma cantidad de elementos. Esto se usará para cada fila en tablas muy grandes, por lo que prefiero que no haya una función iterativa si es posible.
Aquí hay un ejemplo de lo que quiero lograr:
lista1 = {"a","b","c","d","e","f","g"};
lista2 = {"1","2","3","4","5","6","7"};
El resultado aceptable puede ser una cadena o una lista. Si es una cadena separada por delimitadores.
Resultado de la lista: {"a,1","b,2","c,3","d,4","e,5","f,6","g,7"};
Resultado de la cadena: "a:1,b:2,c:3,d:4,e:5,f:6,g:7";
La personalización en masaRe: Concatenar varios elementos de la lista juntos¡Hice un lío con eso! Aquí hay una versión actualizada que probablemente funcionará correctamente en versiones anteriores 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 )} )
)
);ver Lista rápida para una explicación; Me estaba concentrando en la función RemoveFrom y me olvidaba de la función Insertar en.
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.Insertar en necesita un tercer argumento para insertar al principio de la lista, y luego un reverso cuando haya terminado.
También cambié el nombre de las variables en el ciclo para que no usaran las columnas de la tabla de datos como temporales.
Re: Concatenar varios elementos de la lista juntosMi problema está resuelto: esto es más un FYI para usted y otros que puedan encontrarlo útil.
Tengo acceso a JMP14.3, pero el script debe ejecutarse en JMP12.2 para que sea compatible con mi organización.
Intenté su análisis y para JMP14.3 obtuve resultados similares a los suyos, probablemente algunas diferencias en el poder de cómputo.

Sin embargo, JMP12.2 el rendimiento del bucle se sale completamente de la línea. Tengo que matar el proceso JMP.exe después de 98304 ya que el tiempo aumentaba exponencialmente y nunca hubiera llegado a la fila 24:

Re: Concatenar varios elementos de la lista juntosGracias esto funciona muy bien. Aunque utiliza una función iterativa, tiene un buen rendimiento.
Re: Concatenar varios elementos de la lista juntosSí, es posible que haya estado asumiendo que el iterativo (para) dentro del iterativo (para cada fila) afectaría gravemente el rendimiento del script, pero después de compilar el ejemplo @SDF1 sugirió que el rendimiento es sorprendentemente bueno.
Gracias por la comparación. Habría asumido que c ++ siempre sería más rápido, pero tiene sentido que una tabla siempre tenga más gastos generales. Me pregunto si la tabla "Comenzar actualización de datos" y/o "Privada" mejoraría la sobrecarga de la tabla.
Re: Concatenar varios elementos de la lista juntosLos bucles JSL tienen una reputación inmerecidamente mala. Si las entrañas del bucle hacen mucho trabajo, la sobrecarga del bucle normalmente no importará mucho. Y cualquier solución sin un bucle JSL implicará un bucle en otro lugar, tal vez en C ++, que será un poco más rápido, pero aún así. De todos modos, aquí hay una comparación de dos métodos, uno que involucra un bucle JSL y otro que usa un bucle oculto en el código 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.Gráfico que muestra los tiempos de cruce de los dos algoritmos en alrededor de 39 000 elementos.
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 es el más antiguo al que tengo acceso. Creo que el algoritmo de bucle tendrá un rendimiento similar en JMP 12. Destruye intencionalmente las dos listas mientras las procesa porque las versiones anteriores de JMP no tenían una indexación rápida en las listas, pero eliminar el primer elemento es rápido. El algoritmo de la tabla de datos es el primero en el ciclo, por lo que puede usar las listas antes de que se destruyan.
Mirando hacia atrás en el JSL, no debería afirmar que ninguno de los algoritmos es más simple o más fácil de seguir.
Re: Concatenar varios elementos de la lista juntosHola @ts2 ,
Dependiendo de lo que quiera hacer con los resultados, puede abordarlo de un par de maneras diferentes. Sé que no quieres hacer funciones iterativas, pero para obtener el resultado correcto donde los elementos de una lista están conectados a los elementos de otra lista, creo que tienes que hacer un For Loop. También podría considerar hacer una matriz asociativa.
A continuación se muestra un JSL que podría ayudarlo a comenzar con una solución.
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);¡Espero que esto ayude!,
SD