2013-08-20 2 views
1

나는 다음과 같습니다 csv 파일에서 데이터를 구문 분석 :텍스트 구문 분석과 중첩 컬렉션 조옮김은

X,..,..,Dx,..,.. 
Y,..,..,Dy,..,.. 
X,..,..,Dx,..,.. 
Y,..,..,Dy,..,.. 
X,..,..,Dx,..,.. 
Y,..,..,Dy,..,.. 

각 행은 내가 정의 FileHelpers에 사용되는 유형의 배열의 요소입니다. 이것은 아마도 관련이없는,하지만 난이 넣다 누군가가 내가 FileHelpers를 사용하여 프로세스의이 단계에서 할 수있는 트릭을 알고 포함하고있다.

나는 데이터는 이상을 가질 수 쌍 X, DX를하고 Y, Dy가 에만 관심이있어 단지 X & Y 예 .. (X, DX를); (Y, Dy); (Z, Dz); ...

나는 모든 D의 (nIterations SUM이있는 배열을 처리하여 각 그룹에 대한 문자의 수를 거리 nL

목표는 DX를, Dy가의 평균을 얻는 것입니다 ... 전화 할게) * nL 요소.

나는 반복 번호 목록이 있습니다. "편지 그룹"

let nIterations = [2000; 2000; 2000; 1000; 500; 400; 400; 400; 300; 300] 

그리고이 숫자의 각

, 나는 많은 것을 가질 것이다 따라서, nIterations [0]에 대한 관심 데이터 행은 행 0 ~ (nIterations. [0] * nL)입니다.

nIterations [i]에 관심있는 행을 가져 오려면, "nis 이는 nIterations에서 수행 된 스캔 작업의 결과입니다. 이어서

let nis = List.scan (fun x e -> x + e) 0 nIterations 

nItertions을 분리하는 [I] 기 .. 여기서

let group = Array.sub Ds (nis.[i]*nL) (nIterations.[i]*nL) 

가 전부이다 :.

"청크"함수 I은 SO에서 볼 하나
nIterations |> List.mapi (fun i ni -> 
    let igroup = Array.sub Ds (nis.[i]*nL) (ni*nL) 
    let groupedbyLetter = (chunk nL igroup) 

    let sums = seq { for idx in 0..(nL - 1) do 
         let d = seq { for g in groupedbyLetter do 
              yield (Seq.head (Seq.skip idx g)) } 
         yield d |> Seq.sum } 

    sums |> Seq.map (fun x -> (x/(float ni)))) |> List.ofSeq 

한다 :

let rec chunk n xs = 
    if Seq.isEmpty xs then Seq.empty 
    else 
     let (ys,zs) = splitAt n xs 
     Seq.append (Seq.singleton ys) (chunk n zs) 

나는 작품이며, 내가 원하는 것을 얻을 수 있습니다 - 크기 nL의 길이 컬렉션. 길이 컬렉션.

문제는 속도입니다 - 작은 데이터 세트에 대한이 유일한 작품; 내가 제시 한 예제에서 작업하고있는 크기가 너무 큽니다. 그것은 청크 기능에 "매달려"옵니다.

그래서 제 질문은 : 어떻게이 모든 프로세스의 속도를 향상 가야합니까? (그리고/또는)

을 그 "전위"를 할 수있는 가장 좋은 (을 얻거나, 더 좋은) 방법은 무엇 나는 내가 할 수있는 그림 : 데이터를 재 배열 할 수

  • 시도 내가 그것을 읽고 있어요로 요소가 직접
  • 작은 단계 또는으로 프로세스를 나눈 인덱스
  • 시도는
  • "통과"???
+2

당신이 CSV 형식 공급자를 사용하여 시도 해 봤나 나에게 준다? http://fsharp.github.io/FSharp.Data/library/CsvProvider.html – mydogisbox

+0

구체적인 입력 예와 구체적인 출력을 제공 할 수 있습니까? 조금 잃어 버렸어 .--). 또한 실행 가능한 소스 코드가 없으면 대답하기가 약간 어렵습니다. 어딘가에서 실행되는 버전을 공유 할 수 있다면 유용 할 것입니다. –

답변

1

알겠습니다.

let averages = 
    (nIterations |> List.mapi (fun i ni -> 
     let igroup = Array.sub Ds (nis.[i]*nL) (ni*nL) 
     let groupedbyLetter = 
      [| for a in 1..nL..igroup.Length do 
        yield igroup.[(a - 1)..(a - 1)+(nL-1)] |] 

     [| for i in 0..(nL - 1) do 
       yield [| for j in 0..(groupedbyLetter.Length - 1) do 
          yield groupedbyLetter.[j].[i] |] 
       |> Array.average |])) 

let columns = [| for i in 0..(nL - 1) do 
        yield [| for j in 0..(nIterations.Length - 1) do 
            yield averages.[j].[i] |] 
        |] 

'열'기능이 너무 I를 쉽게 인쇄 할 수있는 데이터를 다시 전치된다 ..

   ----Average Ds---- 
nIterations  X Y Z 
    2000   0.2 0.7 1.2 
    ...   ... ... ... 
    ...   ... ... ... 

예컨대 평균은

[[x1,y1,z1,..], [x2,y2,z2,..], ... ] 

를 반환하고 열은

[ [x1,x2,..], [y1,y2,..], [z1,z2,..], ...]