4

csv ファイルを特定の txt スキーマに変換する次の関数があります (CNTKTextFormat Reader によって期待されます)。

open System.IO
open FSharp.Data;
open Deedle;

let convert (inFileName : string) = 
    let data = Frame.ReadCsv(inFileName)
    let outFileName = inFileName.Substring(0, (inFileName.Length - 4)) + ".txt"
    use outFile = new StreamWriter(outFileName, false)
    data.Rows.Observations
    |> Seq.map(fun kvp ->
        let row = kvp.Value |> Series.observations |> Seq.map(fun (k,v) -> v) |> Seq.toList
        match row with
        | label::data ->
            let body = data |> List.map string |> String.concat " "
            outFile.WriteLine(sprintf "|labels %A |features %s" label body)
            printf "%A" label
        | _ ->
            failwith "Bad data."
    )
    |> ignore

不思議なことに、F# インタラクティブ パネルで実行した後、出力ファイルが空になり、printfまったく印刷されません。

を削除しignoreて、空のファイルの代わりに、処理中の実際の行があることを確認すると (null のシーケンスを返すことで証明されます)、次のようになります。

val it : seq<unit> = Error: Cannot write to a closed TextWriter.

StreamWriter以前は、手動で使用および破棄を宣言していましたletが、空のファイルまたは数行 (数千のうちの 5 など) も生成しました。

ここで何が起きてるの?また、ファイルの書き込みを修正する方法は?

4

3 に答える 3

7

Seq.map反復されるまで評価されない遅延シーケンスを返します。現在、それを繰り返し処理していconvertないため、行は処理されません。a を返し、Seq<unit>それを外側で反復するとconvertoutFileは既に閉じられているため、例外が表示されます。

Seq.iter代わりに次を使用する必要があります。

data.Rows.Observations
    |> Seq.iter (fun kvp -> ...)
于 2016-12-14T13:32:18.493 に答える