Ciao comunità JMP,
Nei miei script JSL genero spesso nuove colonne una dopo l'altra in questo modo:
...
DT << New Column( "Some Name1", Numeric, "Continuous", Formula( Some Formula1 ) );
DT << New Column( "Some Name2", Numeric, "Continuous", Formula( Some Formula2 ) );
DT << New Column( "Some Name3", Numeric, "Continuous", Formula( Some Formula3 ) );
...
Solitamente le mie tabelle di dati sono piuttosto grandi e possono raggiungere i 100 milioni di righe. Le formule che utilizzo spesso includono funzioni statistiche come Col Media() , Colmassimo() ecc., il che le rende sempre più lente all'aumentare del numero di righe. Potrebbe darsi che alcune nuove colonne dipendano l'una dall'altra, ma per il momento si prega di supporre che non sia così.
Quando eseguo il mio script, vedo che JMP 19.1 utilizza solo il 3-4% della mia CPU (16 core, 32 thread).
È possibile accelerare il calcolo, ad esempio tramite parallelizzazione, senza però creare sottoinsiemi e dover poi unire i risultati ottenuti? Posso lavorare in parallelo sulla stessa tabella di dati utilizzando JSL in JMP?
In caso contrario, pensi che valga la pena provare l'approccio "calcolo della formula del sottoinsieme e successiva unione"?
Saluti
Rob
A seconda del tipo di calcolo (e se hai bisogno di formule o meno), potresti creare una tabella di riepilogo, eseguire i calcoli al suo interno e poi aggiornare i risultati nella tabella principale.
Esiste uno strumento per gestire la parallelizzazione delle matrici: Parallel Assign.
Non sono sicuro che questo velocizzerà effettivamente le cose, a meno che non si stiano creando molte nuove colonne basate su un numero limitato di colonne di input e si abbiano a disposizione funzioni molto limitate.
Ecco un esempio:
Names default to here(1);
dt = Open("$Sample_data/Pollen.jmp");
//first a simple demo of parallel assign to calculate column means
moutmeans = J(n col(dt), 1, .); //blank matrix that will be populated
mdata = dt << get as matrix; //input data as a matrix
Parallel Assign(
{ mdata = mdata }, //variables needed in the 'worker thread'
moutmeans[a, b] = mean(mdata[0,a]); //this fills in one cell
);
show(moutmeans); //col means are here
// Now for new columns
//mdata = mdata[1::2,0]; //a way to start small if you add show()
nrows = nrow(mdata);
cnames = dt << get column names(); //used to find position of columns in matrix
// Write formulas for each columns using column names as placeholders
// to be replaced by matrix values later, this would work for pretty simple logic
formulas = Eval List({
Expr(edge + nub + 10),
Eval Expr(nub - Expr( col mean(dt:nub) ) ) //note this col mean evaluates now
});
newcnames = {"a","b"}; //new column names used later
mout = J(nrows, length(formulas), .); //empty matrix to populate
Parallel Assign(
{
mdata = mdata,
formulas = formulas,
cnames = cnames
},
mout[a, b] = (
f = formulas[b];
//assign values to all potential variables used in matricies
//(bad idea if lots of unused columns)
for(i=1, i<= n items(cnames), i++,
//Make a list with the variable to assign and value to assign it to,
// then replace the list with assign
Eval( Substitute(
Eval List( {as name( name expr( cnames[i] ) ), mdata[a,i]} ),
Expr({}),
Expr( assign() )
) );
);
eval(f);
);
);
//put new columns in table
for each({c,i}, newcnames, dt << New Column(c,Numeric,Continuous, << Set Values(mout[0,i])));
//add columns to double check it worked
dt << New Column("a-check", Numeric, "Continuous", Format("Best", 12), Formula(:edge + :nub + 10));
dt << New Column("b-check", Numeric, "Continuous", Format("Best", 12), Formula(:nub - Col Mean(:nub)));
Potresti provare a sopprimere la valutazione delle formule finché non sono state create tutte le colonne, quindi utilizzare Esegui formule.
( @Ryan_Gilmore , @Robbbb ) dt<
Ecco un elemento della lista dei desideri per cui votare
valutazione della formula di base