我有从管道分隔字符串格式的数据库中检索的数据。 例如“70|71|69|78”。
它们确实是很长的字符串,我有一个很大的数据集。
我需要做的是将字符串转换为矩阵(实际上是向量)并对结果向量(最大值、第 95 个百分位数等)进行一些操作
这是我今天的做法:
ExampleStr = "70|71|71|72|72|72|72|72|74|74|74|74|74|74|74|74|74|74|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|75|76|75|75|76|76|76|75|75|76|76|75|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|77|76|76|76|76|76|76|76|76|76|76|76|76|77|76|76|76|76|76|76|77|76|77|76|77|76|76|77|76|76|76|76|76|76|76|76|77|76|76|76|76|77|77|77|77|76|76|77|77|76|76|76|76|77|76|77|76|76|76|76|76|77|76|76|76|77|77|77|76|76|77|76|76|76|77|76|76|76|76|76|76|77|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|77|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|76|77|76|76|76|76|76|76|76|76|76|77|77|77|77|77|77|77|77|76|77|77|76|76|77|76|76|77|76|77|76|77|76|77|77|77|76|76|76|77|77|76|76|77|76|76|76|76|76|76|76|77|76|76|76|76|76|76|76|77|77|77|76|77|77|76|76|77|76|77|76|77|77|77|77|77|76|76|77|77|77|77|77|77|76|76|77|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|76|77|77|76|76|76|77|77|77|77|77|77|77|77|77|76|76|77|77|77|77|77|77|77|77|77|77|76|76|76|77|77|77|77|77|77|76|77|77|77|76|77|77|77|77|76|76|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|76|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|76|77|77|76|77|77|77|77|76|77|76|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|76|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|77|76|77|77|77|77|77|77|77|77|77|77|77|77|77|78|78|78|78|78|78|78|78|78|78|77|78|78|77|78|77|77|77|78|78|78|78|78|78|77|78|77|78|78|78|78|78|78|77|78|78|78|77|78|77|78|78|78|77|78|77|78|78|78|78|78|77|78|78|78|78|78|78|78|78|78|77|78|78|78|77|78|78|78|77|77|78|78|78|78|78|78|78|78|78|78|78|78|78|77|77|78|77|77|78|77|78|78|78|78|78|78|78|78|77|77|78|78|78|77|77|78|78|78|78|78|78|78|78|78|78|78|78|77|78|78|78|78|78|78|77|78|78|78|78|77|78|78|78|78|77|77|78|78|78|78|78|78";
t1 = HPTime();
V = parse("["||substitute(ExampleStr,"|",",")||"]") ;
t2 = HPTime();
show((t2-t1)/1000); // takes about 0.9 milliSec所以我用逗号替换管道,然后通过前缀和后缀矩阵括号使字符串看起来像一个矩阵。 那部分很快。
大部分时间花在了 Parse() 调用上。
对于管道分隔字符串中包含 775 个值的示例,执行上述代码大约需要 0.9 毫秒。
这可能看起来时间很少,但我需要它至少减少一个数量级。 因为我的数据表,在我现在的例子中,有762000行数据!
不是每个字符串都是 775 个值,有些更短,也不是每次迭代都需要 0.9 毫秒,但总共花了将近 10 分钟来浏览数据表并做我需要做的事情,就像这样:
dt << new column("P95_Value");
foreachrow(
V = parse("["||substitute(:StrColumn,"|",",")||"]") ;
:P95_Value = VQuantile(V,0.95);
);VQuantile() 调用不是问题,它非常快。 大部分时间都在 parse() 行上。
我只是想知道是否有更智能的方法来处理这个字符串并将其转换为向量,理想情况下更接近 0.09 毫秒或更好!
我认为这不是一个聪明的方法,而是更快一点。 当数据有 762,000 行时,在我的计算机上大约需要 3 分钟。
Names Default To Here( 1 );
dt = Current Data Table();
t1 = HP Time();
//Subset data table
subset = dt << Subset(
All rows,
Selected columns only( 0 ),
columns( :StrColumn )
);
subset << show window(0);
subset << Begin Data Update;
//Text to Column
subset << Text to Columns( columns( :StrColumn ), Delimiters( "|" ) );
// Change Character to Numeric
subset << delete column(:StrColumn);
col_ref_list = subset << Get Column Reference();
For Each( {col, index}, col_ref_list, col << Data Type( Numeric, Format( "Best", 12 ) ) );
//Get 95% Percentile
mt = subset << get as matrix();
P95_value_mt = Transpose( V Quantile( Transpose( mt ), 0.95 ) );
close(subset,nosave);
//Set Value to Column
dt << New Column( "P95_Value" );
:P95_Value << set values( P95_value_mt );
dt << End Data Update;
t2 = HP Time();
Show( (t2 - t1) / 1000000 );