我需要编写一个Deedle FrameData (包括"ID“列和带有空白条目的"Delta”列)到CSV。虽然我可以生成FrameData的2D数组,但无法正确地将其写入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我遗漏了什么?
发布于 2018-05-23 20:36:54
我不会使用FrameData来完成这个任务--帧数据大多是内部的,虽然它有一些合法的用途,但我不认为它对此任务有意义。
如果您只想向输入的CSV中添加一个空的Delta列,那么可以这样做:
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列和额外的Delta列。
唯一的警告是,它没有在数据周围添加额外的引号。这不是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()发布于 2018-05-23 20:21:28
您可以从库的来源获得写入csv的示例(它在那里使用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 https://stackoverflow.com/questions/50493354
复制相似问题