繁体   English   中英

访问csv文件中的条目以进行计算F#

[英]Accessing entries in a csv files for computation F#

如何访问csv文件中的条目以便在F#中对它们执行计算?

我可以用通常的方式将csv文件读入内存,但是一旦我被卡住了。

理想情况下,我只需从列创建数组,然后使用array.map2执行计算。

所以我的数组1是一些网站使用指标,第2列是达到第1列中的值的用户数(比如对网站进行6次访问)我们可以通过乘以数组中的每个条目来计算平均访问次数第1列,由第2列组成的数组,除以第2列的array.sum。

我在F#片段http://fssnip.net/3T上尝试了csv to Array代码,但它为我生成了一系列字符串元组。

有谁能建议更好的方法?

编辑:一些示例输入将类似于: -

     Visits Count
     1  8
     2  9
     3  5
     4  3
     5  2
     6  1
     7  1
    10  1

输出将返回数据的平均值,在这种情况下为2.87(小数点后2位)。

编辑2:从我发现的CSV到阵列代码的当前输出是这个

     val it : seq<BookWindow> =
            seq [{Visits = 1;
                  Count = 8;}; {Visits = 2;
                           Count = 9;}; {Visits = 3;
                                  Count = 5;}; {Visits = 4;
                                              Count = 3;}; ...]

这对计算没那么有用......

我所做的是创建一个记录类型,以便我可以使用强类型操作,然后像下面的代码一样快速地将文本文件读入seq<myRecord> 如果我打算稍后重用它,我通常会将该方法作为static member fromFile移动到记录中。 如果你像我一样使用大型文本文件,seq非常有用,它以这种方式使用非常少的内存。

编辑这个更干净:

open System.IO

type myRecord = { 
    Visits: int
    Count: int 
} with
    static member fromFile file = 
        file
        |> File.ReadLines       // expose as seq<string>
        |> Seq.skip 1           // skip headers
        |> Seq.map (fun s-> s.Split '\t') // split each line into array
        |> Seq.map (fun a -> {Visits=int a.[0]; Count=int a.[1]}) // and create record

myRecord.fromFile @"D:\data.csv"
|> Seq.fold (fun (tv, tc) r -> (tv+r.Visits*r.Count, tc+r.Count))(0,0)
|> (fun t -> float (fst t) / float (snd t))
//val mean : float = 2.866666667

值得补充的是,使用F#3.0类型的提供程序,访问CSV文件变得更加简单。 类型提供程序可以在编译期间静态查看CSV数据,并生成表示列的类型(如BookWindow ),然后它会推断各列的数据类型。

例如,在新版本的Try F#网站上查看“财务建模”下的“使用Yahoo财务类型提供程序”一文。 你可以这样写:

#r "Samples.Csv.dll"

// Type provider that generates schema based on CSV file located online
[<Literal>]
let url = "http://ichart.finance.yahoo.com/table.csv?s=MSFT"
let msft = new Samples.FSharp.CsvProvider.MiniCsv<url>()

// The provider automatically infers the structure and we
// can access columns as properties of the 'row' object
for row in msft.Data do
  printfn "%A %f" row.Date row.Close

据我所知,最新公开版本的CSV提供程序位于F#3.0示例包中 我有一个可能更好的版本,也可以处理我的GitHub仓库上的类型推断。

将数据存储到内存后,可以使用标准F#函数进行计算。 例如,要计算平均收盘价格(您可以尝试尝试F#),您可以写:

 Seq.average [ for row in msft.Data -> row.Close ]

这会生成一个只有收盘价的清单,然后在数字上调用标准平均函数。

你可能过于复杂,这不是最干净的解决方案,但你仍然可以使用你拥有的东西。 将BookWindow类型映射到单独的数组中,如果这提供了一种很好的计算方法。

 type BookWindow = { Visits: int
                     Count: int }
 // Sample data
 let list = [|{Visits = 1; Count = 8;}; {Visits = 2; Count = 9;}; {Visits = 3; Count = 5;}|]

 let visitcol = list |> Array.map (fun r -> r.Visits)
 let countcol = list |> Array.map (fun r -> r.Count)
 Array.map2( fun v c -> v * c) visitcol countcol

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM