Bonjour à la communauté JMP,
Dans mes scripts JSL, je génère souvent de nouvelles colonnes les unes après les autres, comme ceci :
...
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 ) );
...
Mes tableaux de données sont généralement assez volumineux et peuvent atteindre 100 millions de lignes. Les formules que j'utilise contiennent souvent des fonctions statistiques comme la moyenne des colonnes (Colonne Mean()) et le maximum des colonnes (Colonne Maximum()), ce qui les rend de plus en plus lentes à mesure que le nombre de lignes augmente. Il est possible que certaines nouvelles colonnes soient interdépendantes, mais veuillez considérer pour l'instant que ce n'est pas le cas.
Lorsque mon script s'exécute, je constate que JMP 19.1 utilise seulement 3 à 4 % de mon processeur (16 cœurs, 32 threads).
Est-il possible d'accélérer le calcul, par exemple par parallélisation, sans créer de sous-ensembles ni fusionner les résultats obtenus ? Puis-je travailler en parallèle sur une même table de données en utilisant JSL dans JMP ?
Sinon, pensez-vous que l'approche « sous-ensemble-calcul de formule-fusion » mérite d'être essayée ?
Acclamations
Voler
Selon vos calculs (et si vous avez besoin de formules ou non), vous pourriez éventuellement créer un tableau récapitulatif, y effectuer les calculs et les mettre à jour dans votre tableau.
Il existe un outil pour gérer la parallélisation des matrices : Parallel Assign.
Je ne suis pas certain que cela accélérera réellement les choses, à moins que vous ne créiez de nombreuses nouvelles colonnes à partir d'un petit nombre de colonnes d'entrée, et que vous soyez très limité quant aux fonctions que vous utilisez.
Voici un exemple :
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)));
Vous pouvez essayer de désactiver l'évaluation des formules jusqu'à ce que toutes les colonnes soient créées, puis utiliser la fonction « Exécuter les formules ».
( @Ryan_Gilmore , @Robbbb ) dt<
Voici un élément de la liste de souhaits pour lequel voter
évaluation de la formule de base