推断任意CSV文件的类型信息?

时间:2015-06-02 20:55:37

标签: f# f#-data f#-scripting compiler-services

我想使用以下控制台程序来获取Csv类型提供程序的类型信息(不是数据)。文件名将作为命令行参数传递。但是,CsvProvider<>似乎只接受常量字面值。

有没有办法解决它?或者是否可以使用F#脚本来完成? 或者F#编译器服务可以帮助吗?

或者还有其他项目吗?

open FSharp.Data
open Microsoft.FSharp.Collections
open System

[<Literal>] 
let fn = """C:\...\myfile.csv""" // Want to dynamically set the fn from arguments

[<EntryPoint>]
let main argv = 
    let myFile = CsvProvider<fn>.GetSample()
    // The following doesn't work
    let fn = argv.[0]
    let myFile = CsvProvider<fn>.GetSample()

    // code to get type information of myFile

2 个答案:

答案 0 :(得分:4)

我认为您可能误解了CSV类型提供程序的用途 - 我们的想法是您在编译时可以获得有代表性的数据样本(并且可以使用它来指导类型推断)。在运行时,您只需使用相同的格式(可能是另一个)文件。这为您提供了一种处理已知格式文件的好方法。

如果要解析任意CSV文件(具有不同的标题等),则CSV类型提供商不会提供帮助。但是,您仍然可以使用F#Data中的CsvFile类型,它提供了一个简单的CSV解析器。示例from the documentation

// Download the stock prices
let msft = CsvFile.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")

// Print the prices in the HLOC format
for row in msft.Rows do
  printfn "HLOC: (%s, %s, %s)" (row.GetColumn "High") 
     (row.GetColumn "Low") (row.GetColumn "Date")

在这里,你放弃了很好的静态类型,但你可以用任何格式加载文件(然后动态查看文件中可用的列)。

答案 1 :(得分:1)

Tomas建议,以下F#-Data CSV提供程序功能可用于解决此问题。

let data = CsvFile.Load(....)
let inferredProperties =
    // InferColumnTypes : inferRows:int 
    // * missingValues:string [] 
    // * cultureInfo:CultureInfo 
    // * schema:string 
    // * assumeMissingValues:bool 
    // * preferOptionals:bool 
    // * ?unitsOfMeasureProvider:IUnitsOfMeasureProvider 
    // -> PrimitiveInferedProperty list
    data.InferColumnTypes(10000, [|""|], CultureInfo.InvariantCulture, "", false, true)

不确定应该使用哪些参数。但上面的设置似乎没问题。