使用F#清洗CSV数据集:列值转小写、数据结构选择及加载保存方案咨询
使用F#清洗CSV数据集:两种实现方案
方案一:直接通过CsvProvider的Rows处理
这种方式无需转换为列表,直接利用CsvProvider的类型安全特性处理每行数据,适合简单修改场景,性能开销更低。
步骤1:加载CSV
先定义CsvProvider类型(可指定实际CSV文件路径,或内联样本数据作为结构参考):
open FSharp.Data // 假设你的CSV列结构为:Id,Name,Email type CsvData = CsvProvider<"input.csv"> let originalData = CsvData.Load("input.csv")
步骤2:修改指定列(示例:将Name列转为小写)
CsvProvider生成的行对象是不可变的,需构造新行保留其他列原值,仅修改目标列:
let modifiedRows = originalData.Rows |> Seq.map (fun row -> CsvData.Row( row.Id, row.Name.ToLower(), // 目标列转小写 row.Email ) )
步骤3:保存修改后的CSV
通过Replace方法生成包含修改后行的新CsvData实例,再保存为文件:
let modifiedData = CsvData.GetSample().Replace(modifiedRows) modifiedData.Save("output.csv")
方案二:转换为记录/结构体列表处理
如果需要复杂的集合操作(如过滤、分组、多列联动修改),可先将Rows转为自定义记录类型列表,处理后再转回可保存格式。
步骤1:定义记录类型并加载转换
open FSharp.Data // 定义与CSV列匹配的记录类型 type User = { Id: int; Name: string; Email: string } type CsvData = CsvProvider<"input.csv"> let originalData = CsvData.Load("input.csv") // 将Rows转换为User列表 let userList = originalData.Rows |> Seq.map (fun row -> { Id = row.Id; Name = row.Name; Email = row.Email } ) |> List.ofSeq
步骤2:修改指定列
利用记录的不可变更新语法修改目标列:
let modifiedUserList = userList |> List.map (fun user -> { user with Name = user.Name.ToLower() })
步骤3:保存为CSV
有两种常见方式:
// 方式1:转回CsvData.Row序列后保存(类型安全) let modifiedRows = modifiedUserList |> Seq.map (fun user -> CsvData.Row(user.Id, user.Name, user.Email) ) let modifiedData = CsvData.GetSample().Replace(modifiedRows) modifiedData.Save("output.csv") // 方式2:直接生成CSV字符串(适合简单场景) let csvHeader = "Id,Name,Email" let csvRows = modifiedUserList |> List.map (fun user -> $"{user.Id},{user.Name},{user.Email}") let fullCsv = String.concat "\n" (csvHeader :: csvRows) System.IO.File.WriteAllText("output.csv", fullCsv)
两种方案对比
- 直接用Rows处理:类型安全,无需额外定义数据结构,适合单列简单修改,性能更优。
- 转换为列表处理:灵活性更高,支持复杂集合操作,适合深度数据清洗场景。
内容的提问来源于stack exchange,提问作者grep
相关产品推荐
相关产品推荐

