f# - F# - 将 Deedle FrameData 写入 CSV
问题描述
我需要将Deedle FrameData(包括“ID”列和带有空白条目的附加“Delta”列)写入 CSV。虽然我可以生成FrameData的二维数组,但我无法将其正确写入 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
我错过了什么?
解决方案
我不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
列和额外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()
推荐阅读
- ssas - 来自 AdventureWorks 的 SSAS 不同销售客户
- android - 如何从 Android AOSP 代码库构建单个模块
- sql - 按需 Postgres 临时视图的性能影响
- swift - SwiftUI 添加倒置遮罩
- amazon-web-services - 将 POST API 请求中的数据传递给 lambda 函数
- swift - 为什么过滤器数据不显示在表格视图中?
- amazon-web-services - 授予 EC2 实例中的代码访问另一个账户的 S3 存储桶的权限
- python-3.x - Tkinter 如何立即销毁在 Python 函数调用中创建的窗口?
- javascript - 如何使用javascript获取li的id值
- flutter - 将 Flutter 提供程序与 Firestore 一起使用的最佳方式是什么