在HtmlProvider中自动键入列<...>.Table.Row>

Sus*_*ver 7 f# f#-data

FSharp.Data HTMLProvider用来提取表行:

let [<Literal>] URL = "../DailyResultsType.html"
type RawResults = HtmlProvider<URL>
let results = RawResults.Load(URL).Tables
let dailySeq =
    results.Table2.Rows
    |> Seq.tail
Run Code Online (Sandbox Code Playgroud)

循环遍历行(row是a seq<HtmlProvider<...>.Table2.Row>):

for row in dailySeq do
    printfn "%A" row
Run Code Online (Sandbox Code Playgroud)

结果是:

(1, nan, nan, 2)
(1, nan, nan, 3)
~~~
Run Code Online (Sandbox Code Playgroud)

像#2和#3这样的列由提供者自动输入decimal,double因为HTML包含诸如"$ 12.00"或"$ 12"之类的字符串.

  • 我可以动态改变这些列的类型从返回的类型HtmlProvider<URL>在运行时(从双串即)(但我更喜欢数字类型,所以我可以Deedle结果)

  • 或者将运行时字符串转换应用于这些列中的值以删除非数字字符,以便它们是有效的decimal/double/int类型...

  • 或者我错过了一个基本概念(很可能是因为我是F#noobie)

s95*_*163 0

我认为你应该尝试将 PreferOptionals 设置为 true,这样 N/A 将变为 null,其余数字将变为小数。

\n\n

type HtmlType = HtmlProvider<URL,PreferOptionals=true>
\ntype HtmlType = HtmlProvider<URL,PreferOptionals=true,Culture="en-US">

\n\n
let results = HtmlType.Load(URL)\nresults.Tables.Table1.Rows\n// val it : HtmlProvider<...>.Table1.Row [] =\n// [|("Jill", "Smith", Some 50.0M); ("Eve", "Jackson", Some 100000M);\n// ("John", "Doe", Some 100M); ("Jane", "Doe", null)|]\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果表中没有缺失值,并且我省略了 PreferOptionals 和 Culture,那么我会得到以下输出:

\n\n
//val it : HtmlProvider<...>.Table1.Row [] =\n//[|("Jill", "Smith", 50.0M); ("Eve", "Jackson", 100000M);\n//("John", "Doe", 100M)|]\n
Run Code Online (Sandbox Code Playgroud)\n\n

顺便说一句,我可能是错的,但我找不到任何可以像 csv 提供程序中那样指定表架构的内容。因此,一旦我取出数据,如果没有那么多应该简单的元素,我将直接使用元组数组。string如果需要,您可以使用或直接通过管道将其传递给 Deedle ( rows |> Frame.ofRecords)。

\n\n

我使用了以下示例表。

\n\n

\r\n
\r\n
let results = HtmlType.Load(URL)\nresults.Tables.Table1.Rows\n// val it : HtmlProvider<...>.Table1.Row [] =\n// [|("Jill", "Smith", Some 50.0M); ("Eve", "Jackson", Some 100000M);\n// ("John", "Doe", Some 100M); ("Jane", "Doe", null)|]\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n