FSharp.Data 程序集之 CSV 文件解析
(**
# FSharp.Data 程序集之 CSV 文件解析
F# 的 [CSV 类型提供程序](CsvProvider.html)是在用 F# 编写的、高效的 CSV 分析器之上构建立的,还提供了简单的 API 进行动态访问。
在处理定义很好的 CSV 文件时,使用[类型提供程序](CsvProvider.html)更方便,但有一个更加动态的场景,或者编写快速、简单的脚本时,解析器可能是一个简单的选择。
## 加载 CSV 文档
要加载一个样本 CSV 文档,要先引用 `FSharp.Data.dll`(使用 F# Interactive)或者在项目中添加引用。
*)
#r "../../bin/FSharp.Data.dll"
open FSharp.Data.Csv
(**
`FSharp.Data.Csv` 命名空间包含 `CsvFile` 类型,提供了两个静态方法,用来加载数据。如果数据是在 `string` 中,就使用 `Parse` 方法,而当数据来自于文件或网站,就使用 `Load` 方法。下面的示例调用 `Load` 方法,参数为指向 Yahoo 财经网站上实时的 CSV 文件:
*)
// 下载股票价格
let msft = CsvFile.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT").Cache()
// 以 HLOC 格式输出价格
for row in msft.Data do
printfn "HLOC: (%s, %s, %s)" (row.GetColumn "High") (row.GetColumn "Low") (row.GetColumn "Date")
(**
注意,与 `CsvProvider` 不同,出于性能上考虑,`CsvFile` 以流方式工作,就是说,`Data` 只重复一次。如果需要多次重复使用,请使用 `Cache` 方法。不过要注意,这会增加内在的开销,尤其在大数据集上不要使用。
## 使用 CSV 扩展
现在,我们来看一下,当打开 `FSharp.Data.Csv.Extensions` 命名空间后,有许多扩展。打开之后,就可以:
1、`row?column` 使用动态运算符获得名为 `column` 列的值。当然,也可以使用索引器,`row.[column]`;
2、`value.AsBoolean()` 会返回逻辑值,如果是 `true` 或 `false`;
3、`value.AsInteger()` 会返回整型值,如果是数字,且能转换成整数;`value.AsInteger64()`, `value.AsDecimal()` 和 `value.AsFloat()` 也相似;
4、`value.AsDateTime()` 会返回日期值,既可以使用 [ISO 8601](http://en.wikipedia.org/wiki/ISO_8601) 格式,也可以使用 `\/Date(...)\/` JSON 格式,包含自 1/1/1970 以来的毫秒数;
5、`value.AsGuid()` 会返回 `Guid` 值。
要解析数字或日期值(比如,`AsFloat` 和 `AsDateTime`)时,方法可能需要一个或选的语言参数。
下面的示例使用扩展处理前面 CSV 样本:
*)
open FSharp.Data.Csv.Extensions
for row in msft.Data do
printfn "HLOC: (%f, %M, %O)" (row.["High"].AsFloat()) (row?Low.AsDecimal()) (row?Date.AsDateTime())
(**
## 转换 CSV 文件
除了能读 CSV,`CsvFiles` 还能转换 CSV 文件。操作包括: `Filter`, `Take`, `TakeWhile`, `Skip`, `SkipWhile`, 和 `Truncate`。转换完之后,能用重载的 `Save` 方法保存结果。保存时,可以选择不同的分隔符和引号字符。
*)
// 保存前 10 个股票价格,且收盘价大于开盘价,用 TSV 格式:
msft.Filter(fun row -> row?Close.AsFloat() > row?Open.AsFloat())
.Truncate(10)
.SaveToString('\t')
.Save("a10.csv",'`')
(**
## 相关文章
* [FSharp.Data 程序集之 CSV Type Provider](CsvProvider.html) - 讨论 F# 类型提供程序,提供类型安全地访问 CSV 数据
*)