Tengo datos que recupero de una base de datos que está en un formato de cadena delimitado por tubería. Por ejemplo, "70|71|69|78".
Son cadenas realmente largas y tengo un gran conjunto de datos de ellas.
Lo que necesito hacer es convertir las cadenas en una matriz (vector realmente) y hacer algunas operaciones en el vector resultante (Max, percentil 95, etc.)
Así es como lo estoy haciendo hoy:
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 milliSecAsí que reemplacé las tuberías con comas, luego hago que la cadena se vea como una matriz al agregarle el prefijo y el sufijo entre paréntesis de matriz. Esa parte es rápida.
Donde pasa la mayor parte del tiempo es en la llamada Parse().
Para este ejemplo con 775 valores en la cadena delimitada por conductos, se tarda aproximadamente 0,9 ms en realizar el código anterior.
Eso puede parecer muy poco tiempo, pero necesito que sea al menos un orden de magnitud menos. ¡Porque mi tabla de datos, en mi ejemplo actual, tiene 762,000 filas de datos!
No todas las cadenas tienen 775 valores de largo, algunas son más cortas y no todas las iteraciones toman 0.9 mS, pero en total tomó casi 10 minutos revisar la tabla de datos y hacer lo que necesito hacer, que es algo como esto:
dt << new column("P95_Value");
foreachrow(
V = parse("["||substitute(:StrColumn,"|",",")||"]") ;
:P95_Value = VQuantile(V,0.95);
);La llamada a VQuantile() no es un problema, es muy rápida. La mayor parte del tiempo pasa en la línea parse().
Me preguntaba si hay alguna forma más inteligente de procesar esta cadena y convertirla en un vector, ¡idealmente en más de 0.09 milisegundos o mejor!
Creo que no es una forma inteligente, pero un poco más rápido. Toma alrededor de 3 minutos en mi computadora cuando los datos tienen 762,000 filas.
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 );