c# - 使用静态类型语言 (F#) 处理异构数据

标签 c# .net f#

F# 的其中一项声明是它允许交互式脚本和数据操作/探索。我一直在玩弄 F#,试图了解它与 Matlab 和 R 在数据分析工作方面的比较。显然 F# 不具备这些生态系统的所有实用功能,但我更感兴趣的是底层语言的一般优点/缺点。

对我来说,即使是函数式风格,最大的变化是 F# 是静态类型的。这有一定的吸引力,但也常常让人感觉像是一件紧身衣。例如,我还没有找到一种方便的方法来处理异构矩形数据——想想 R 中的数据框。假设我正在读取一个包含名称(字符串)和权重(浮点)的 CSV 文件。通常我加载数据,执行一些转换,添加变量等,然后运行分析。在 R 中,第一部分可能如下所示:

df <- read.csv('weights.csv')
df$logweight <- log(df$weight)

在 F# 中,不清楚我应该使用什么结构来执行此操作。据我所知,我有两个选择:1) 我可以首先定义一个强类型的类 (Expert F# 9.10) 或 2) 我可以使用异构容器,例如 ArrayList。静态类型的类似乎不可行,因为我需要在加载数据后以临时方式(logweight)添加变量。异构容器也不方便,因为每次访问变量时都需要将其拆箱。在 F# 中:

let df = readCsv("weights.csv")
df.["logweight"] = log(double df.["weight"])

如果这是一次或两次,可能没问题,但是每次 使用变量时都指定一个类型似乎不合理。我经常处理包含 100 个变量的调查,这些变量被添加/删除,分成新的子集并与其他数据框合并。

我是否遗漏了一些明显的第三选择?是否有一些有趣且轻松的方式来交互和操作异构数据?如果我需要在 .Net 上做数据分析,我目前的感觉是我应该使用 IronPython 来完成所有的数据探索/转换/交互工作,并且只使用 F#/C# 来处理数值密集的部分。 F# 是否天生就是用于处理快速而肮脏的异构数据工作的错误工具?

最佳答案

Is F# inherently the wrong tool for quick and dirty heterogeneous data work?

对于完全临时的、探索性的数据挖掘,我不推荐 F#,因为类型会妨碍您。

但是,如果您的数据定义得很好,那么您可以通过将所有类型映射到一个通用的 F# 联合,将不同的数据类型保存在同一个容器中:

> #r "FSharp.PowerPack";;

--> Referenced 'C:\Program Files\FSharp-1.9.6.16\bin\FSharp.PowerPack.dll'

> let rawData =
    "Name: Juliet
     Age: 23
     Sex: F
     Awesome: True"

type csv =
    | Name of string
    | Age of int
    | Sex of char
    | Awesome of bool

let parseData data =
    String.split ['\n'] data
    |> Seq.map (fun s ->
        let parts = String.split [':'] s
        match parts.[0].Trim(), parts.[1].Trim() with
        | "Name", x -> Name(x)
        | "Age", x -> Age(int x)
        | "Sex", x -> Sex(x.[0])
        | "Awesome", x -> Awesome(System.Convert.ToBoolean(x))
        | data, _ -> failwithf "Unknown %s" data)
    |> Seq.to_list;;

val rawData : string =
  "Name: Juliet
     Age: 23
     Sex: F
     Awesome: True"
type csv =
  | Name of string
  | Age of int
  | Sex of char
  | Awesome of bool
val parseData : string -> csv list

> parseData rawData;;
val it : csv list = [Name "Juliet"; Age 23; Sex 'F'; Awesome true]

csv list 是强类型的,您可以对其进行模式匹配,但您必须预先定义所有联合构造函数。

我个人更喜欢这种方法,因为它比使用非类型化 ArrayList 好几个数量级。但是,我不太确定你的要求是什么,而且我不知道表示临时变量的好方法(除了可能作为 Map{string, obj})所以YMMV.

关于c# - 使用静态类型语言 (F#) 处理异构数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1798920/

相关文章:

c# - 我应该将 id 还是实体传递到我的服务中

c# - 分配字节数组对性能至关重要吗?

c# - 从 C++/CLI 调用 C# dll 时出现 FileNotFoundException

c# - 如何从多个类库中引用配置信息?

generics - 具有通用约束的类型扩展不会引发错误,也不会执行预期的操作

recursion - 如何使用表示状态的函数在 F# 中获得工作状态机?

interface - 使用通用 lambda 处理接口(interface)集合的方法

c# - 创建两个不会在 ASP.NET MVC 中生成 404 错误的路由的问题

c# - 用于在另一个字符串中查找部分字符串的正则表达式

c# - 在 Unity3D 的build设置中获取下一个场景的名称?