Combinaciones de una lista puesta en columnas.Estoy tratando de tomar una lista de cosas y hacer que todos los pares de combinaciones posibles aparezcan en un conjunto de dos columnas.Actualmente tengo un script generado que realiza permutaciones (más repeticiones del mismo valor en la columna a frente a la col b), pero tengo dificultades para reducirlo a combinaciones. Por ejemplo, si la lista de cosas era 1, 2, 3, 4, 5 entonces no necesito 1/2 y 2/1, o 1/1. A continuación se muestra el guión que tengo actualmente y creo que estoy cerca, solo necesito un poco más para llegar a donde necesito estar. Solo necesito hacer que este script elija estrictamente 2 combinaciones de una lista arbitraria. Este ejemplo en particular utiliza 5 cosas para simplificar.gracias
Names Default To Here( 1 );
New Table( "Test",
Add Rows( 5 ),
New Column( "API 10", Numeric, "Continuous", Format( "Best", 15 ), Set Values( [4238939261, 4238939263, 4238939262, 4238939328, 4238939329] ) ),
);
Test = Data Table( "Test" );
APIs = Test:API 10 << get values;
working = New Table( "TestAPIComb", New Column( "API10" ), New Column( "API102" ), add rows( N Items( APIs ) ^ 2 ) );
APIs2 = Test:API 10 << get values;
theRow = 0;
For( APICNT = 1, APICNT <= N Items( APIs ), APICNT++,
For( API2CNT = 1, API2CNT <= N Items( APIs2 ), API2CNT++,
theRow++;
:API10[theRow] = APIs[APICNT];
:API102[theRow] = APIs[API2CNT];
)
);
Ingeniería de Calidad y ProcesosRe: Combinaciones de una lista puestas en columnasTambién debo mencionar que los ejemplos que usé fueron con cadenas. Si está usando números, puede usar operaciones matriciales directas, que son bastante rápidas... la tabla de 2 millones de filas se genera en 0,3 segundos y la tabla 26choose5 en 0,04 segundos.
Names Default To Here(1);
nums = J(2e3, 1, randominteger(1e9));
t1 = hptime();
astable(shape(nums[nChoosekMatrix( 2e3, 2 )], ., 2));
t2 = hptime();
Print( Eval Insert( "Create table of 2 numbers chosen from 2000: ^(t2-t1)/1e6^ seconds." ) );
// 26 choose 5
nums = J(26, 1, randominteger(1e9));
t3 = hptime();
astable(shape(nums[nChoosekMatrix( 26, 5 )], ., 5));
t4 = hptime();
Print( Eval Insert( "Create table of 5 numbers chosen from 26: ^(t4-t3)/1e6^ seconds." ) );

Re: Combinaciones de una lista puestas en columnasEn cuanto al rendimiento.
El siguiente código genera la tabla de pares de casi 2 millones de filas a partir de un conjunto de 2000 en poco menos de 6 segundos, que es un poco menos de la mitad del tiempo que tomó el bucle. No sé si ese rendimiento es adecuado para sus propósitos. Ojalá sea una opción factible para ti.
Names Default To Here( 1 );
letters = Words( "abcdefghijklmnopqrstuvwxyz", "" );
// create a large list of random strings of length 10. use an AA to remove (unlikely) duplicates
lis = Associative Array( Repeat( {Concat Items( letters[J( 10, 1, Random Integer( 26 ) )], "" )}, 2e3 ) ) << get keys;
t1 = HP Time();
// looping solution
dt = new table( "xx", add rows (2e6), << new column ("X", character), <<NEW column=""></NEW>

Re: Combinaciones de una lista puestas en columnasHola,
La función NChooseK Matrix( ) está hecha a medida para problemas como este. También es razonablemente rápido y especialmente útil para k>2. Consulte el código a continuación para ver un ejemplo de 2 cosas y 5 cosas, elegidas de un conjunto de 26.
Salud,
Brady
names default to here(1);
lis = words("abcdefghijklmnopqrstuvwxyz","");
// original example: choose 2
dt = astable( nchoosekMatrix(nitems(lis), 2), << column names({"x", "y"}) );
dt << new column ("first", character, << set values ( lis[dt:x << get values]));
dt << new column ("second", character, << set values ( lis[dt:y << get values]));
dt << delete columns (1::2);
// a more interesting example: choose 5
dt = astable( nchoosekMatrix(nitems(lis), 5), << column names( words("x1,x2,x3,x4,x5",",") ) );
for each ({ i }, 1::5, //i = 1;
eval (substitute( expr(dt << new column ( "y"||char(i), character, <<SET values=""></SET>Re: Combinaciones de una lista puestas en columnasSin muchos cambios, podría usar la lista inicial como números y luego crear una tabla de conversión para unir valores de caracteres basados en esos valores numéricos.
Re: Combinaciones de una lista puestas en columnasHola @jthi ¿Alguna idea si la lista inicial es una cadena en lugar de un número? Dado que la matriz solo funciona para tipos de datos numéricos.
Re: Combinaciones de una lista puestas en columnasNo sé qué método funcionaría más rápido.Mi sugerencia es ejecutar ambos y ver cuál es el más rápido.
Re: Combinaciones de una lista puestas en columnasGracias. miré lo que @txnelson sugirió y también implementó la unión cartesiana y arrojó 15 resultados en lugar de 10. Luego agregué una condición de selección simple al final donde si la primera columna = la segunda columna, también las eliminé. ¿Alguno de ustedes sabe qué método es más rápido en JMP? Estoy trabajando con un conjunto de datos grande y también probaré ese método matricial, pero no sabía si alguno de ustedes sabe qué debería ser más eficiente.
Re: Combinaciones de una lista puestas en columnasLo más probable es que haya muchas formas de hacer esto (la unión cartesiana @txnelson es un buen punto de partida). Aquí hay una opción que utiliza solo cálculos matriciales:
Names Default To Here(1);
// input list
m = [4238939261, 4238939263, 4238939262, 4238939328, 4238939329];
n_items = N Items(m);
// combination count
comb_count = Summation(i = 1, n_items - 1, i++);
m = Sort Ascending(m);
first_col = [];
second_col = [];
For(i = 2, i <= n_items, i++,
first_col ||= Repeat(m[i - 1], n_items - i + 1)`;
second_col ||= m[Index(i, n_items)]`;
);
dt = New Table("Combinations",
Add Rows(comb_count),
New Column("FirstCol", Numeric, Continuous, Values(first_col)),
New Column("SecondCol", Numeric, Continuous, Values(second_col)),
);

Re: Combinaciones de una lista puestas en columnasAgregué algunas líneas de código que eliminarán las combinaciones duplicadas.Además, le sugiero que investigue
Tablas=>Unirse
en la capacidad de unión cartesiana.

Produce todas las combinaciones posibles mucho más rápido que el código JSL.
Names Default To Here( 1 );
New Table( "Test",
Add Rows( 5 ),
New Column( "API 10", Numeric, "Continuous", Format( "Best", 15 ), Set Values( [4238939261, 4238939263, 4238939262, 4238939328, 4238939329] ) ),
);
Test = Data Table( "Test" );
APIs = Test:API 10 << get values;
working = New Table( "TestAPIComb", New Column( "API10" ), New Column( "API102" ), add rows( N Items( APIs ) ^ 2 ) );
APIs2 = Test:API 10 << get values;
theRow = 0;
For( APICNT = 1, APICNT <= N Items( APIs ), APICNT++,
For( API2CNT = 1, API2CNT <= N Items( APIs2 ), API2CNT++,
theRow++;
:API10[theRow] = APIs[APICNT];
:API102[theRow] = APIs[API2CNT];
)
);
dt = Data Table( "TestAPIcomb" );
// Arange data so order is the same for all rows
For( i = 1, i <= N Rows( dt ), i++,
If( :API102[i] > :API10[i],
hold = :API10[i];
:API10[i] = :API102[i];
:API102[i] = hold;
)
);
// Find the duplicates
dt << Select Duplicate Rows( :API10, :API102 );
// Delete the duplicates
dt << delete rows;