파이프로 구분된 문자열 형식의 데이터베이스에서 검색한 데이터가 있습니다. 예: "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.9mSec가 걸립니다.
아주 적은 시간처럼 보일 수 있지만 최소한 한 자릿수 정도는 줄여야 합니다. 현재 예에서 내 데이터 테이블에는 762,000개의 데이터 행이 있기 때문입니다!
모든 문자열의 길이가 775개는 아니며 일부는 더 짧고 모든 반복이 0.9mS가 걸리는 것은 아니지만 데이터 테이블을 살펴보고 다음과 같은 작업을 수행하는 데 거의 10분이 걸렸습니다.
dt << new column("P95_Value");
foreachrow(
V = parse("["||substitute(:StrColumn,"|",",")||"]") ;
:P95_Value = VQuantile(V,0.95);
);VQuantile() 호출은 문제가 되지 않으며 매우 빠릅니다. 대부분의 시간은 parse() 라인에 갑니다.
이 문자열을 처리하고 이상적으로는 0.09milliSec 이상으로 벡터로 변환하는 더 스마트한 방법이 있는지 궁금했습니다!
현명한 방법은 아니지만 조금 더 빠른 방법이라고 생각합니다. 데이터가 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 );