代码之家  ›  专栏  ›  技术社区  ›  matekus

f-将deedle framedata写入csv

  •  2
  • matekus  · 技术社区  · 6 年前

    我需要写一个 迪德尔 框架数据 (包括“id”列和其他带空白条目的“delta”列)到csv。而我可以生成一个二维数组 框架数据 ,无法将其正确写入csv文件。

    module SOQN = 
    
        open System
        open Deedle
        open FSharp.Data
    
        //  TestInput.csv
        //  ID,Alpha,Beta,Gamma
        //  1,no,1,hi
        //  ...
    
        //  TestOutput.csv
        //  ID,Alpha,Beta,Gamma,Delta
        //  1,"no","1","hi",""
        //  ...
    
        let inputCsv = @"D:\TestInput.csv"
        let outputCsv = @"D:\TestOutput.csv"
        let (df:Frame<obj,string>) = Frame.ReadCsv(inputCsv, hasHeaders=true, inferTypes=false, separators=",", indexCol="ID")
    
        // See http://www.fssnip.net/sj/title/Insert-Deedle-frame-into-Excel
        let data4Frame (frame:Frame<_,_>) = frame.GetFrameData()
    
        // See http://www.fssnip.net/sj/title/Insert-Deedle-frame-into-Excel
        let boxOptional obj =
            match obj with
            | Deedle.OptionalValue.Present obj -> box (obj.ToString()) 
            | _ -> box ""
    
        // See http://www.fssnip.net/sj/title/Insert-Deedle-frame-into-Excel
        let frameToArray (data:FrameData) =
            let transpose (array:'T[,]) =
              Array2D.init (array.GetLength(1)) (array.GetLength(0)) (fun i j -> array.[j, i])
            data.Columns
            |> Seq.map (fun (typ, vctr) -> vctr.ObjectSequence |> Seq.map boxOptional |> Array.ofSeq)
            |> array2D
            |> transpose
    
        let main = 
            printfn ""
            printfn "Output Deedle FrameData To CSV"
            printfn ""
            let dff = data4Frame df
            let rzlt = frameToArray dff     
            printfn "rzlt: %A" rzlt     
            do 
                use writer = new StreamWriter(outputCsv)
                writer.WriteLine("ID,Alpha,Beta,Gamma,Delta")
                // writer.WriteLine rzlt
            0
    
        [<EntryPoint>]
        main
        |> ignore
    

    我错过了什么?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Tomas Petricek    6 年前

    我不会用 FrameData 要做到这一点,框架数据主要是内部的,虽然它有一些合法的用途,但我认为它对这个任务没有意义。

    如果您只想添加一个空的 Delta 列到您的输入csv,然后您可以执行此操作:

    let df : Frame<int, _> = Frame.ReadCsv("C:/temp/test-input.csv", indexCol="ID")
    df.AddColumn("Delta", [])
    df.SaveCsv("C:/temp/test-output.csv", ["ID"])
    

    这几乎能满足你的所有需求-它写下 ID 列和额外的 三角洲 列。

    唯一需要注意的是,它不会在数据周围添加额外的引号。这不是csv规范所要求的,除非您需要在列中转义逗号,而且我认为没有一种简单的方法可以让deedle这样做。

    所以,我想你应该把你自己写的东西写进一个csv文件。下面显示了如何执行此操作,但它没有正确转义引号和逗号(这就是您应该使用的原因 SaveCsv 即使在不需要时不加引号):

    use writer = new StreamWriter("C:/temp/test-output.csv")
    writer.WriteLine("ID,Alpha,Beta,Gamma,Delta")
    for key, row in Series.observations df.Rows do
      writer.Write(key)
      for value in Series.valuesAll row do
        writer.Write(",")
        writer.Write(sprintf "\"%O\"" (if value.IsSome then value.Value else box ""))
      writer.WriteLine()
    
        2
  •  1
  •   FoggyFinder    6 年前

    您可以从中获取写入csv的示例 source 图书馆(它使用 FrameData 那里)

    添加包装后:

    type FrameData with 
        member frameData.SaveCsv(path:string, ?includeRowKeys, ?keyNames, ?separator, ?culture) = 
          use writer = new StreamWriter(path)
          writeCsv writer (Some path) separator culture includeRowKeys keyNames frameData
    

    你可以这样写:

    dff.SaveCsv outputCsv 
    
    推荐文章