JMP社区的各位朋友,大家好!
在我的 JSL 脚本中,我经常像这样逐列生成:
...
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 ) );
...
通常我的数据表非常大,可以达到上亿行。我使用的公式经常包含统计函数,例如列均值 (Col Mean()) 、列最大值 (Col Maximum())等,这导致行数越多,计算速度就越慢。可能有些新列之间存在依赖关系,但请暂时假设它们之间没有依赖关系。
我的脚本运行结果显示,JMP 19.1 只使用了我 16 核 32 线程的 CPU 3-4%。
是否可以加速计算(例如通过并行化),但无需构建子集并合并子集结果?我能否在 JMP 中使用 JSL 并行处理同一个数据表?
如果不行,你认为“子集公式计算-合并”的方法值得一试吗?
干杯
抢
根据您的计算(以及是否需要公式),您可以创建一个汇总表,在其中进行计算,然后将结果更新回您的表格。
有一个工具可以用来管理矩阵的并行化:并行分配。
除非你基于少量输入列创建大量新列,并且你使用的函数非常有限,否则我不确定这是否真的能加快速度。
以下是一个例子:
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)));
您可以尝试在创建所有列之前抑制公式计算,然后再使用“运行公式”。