【问题标题】:Expanding JSON to columns of a deedle dataframe将 JSON 扩展到 deedle 数据框的列
【发布时间】:2018-01-14 17:06:16
【问题描述】:

我正在尝试将从网站获得的 JSON 转换为 deedle 数据框,将 JSON 条目扩展为数据框的单独列。我找到了this discussion,但我无法让建议的解决方案为我工作。由于我是 JSON 和 deedle 的新手,我可能会犯一个愚蠢的错误。我正在尝试以下方法(主要从引用的讨论中复制):

let rec expander key value =
    seq {
        match value with
        | JsonValue.String  (s) -> yield key,typeof<string>,box s
        | JsonValue.Boolean (b) -> yield key,typeof<bool>,box b
        | JsonValue.Float   (f) -> yield key,typeof<float>,box f
        | JsonValue.Null    (_) -> yield key,typeof<obj>,box ()
        | JsonValue.Number  (n) -> yield key,typeof<decimal>,box n
        | JsonValue.Record  (r) -> yield! r |> Seq.collect ((<||)expander)
        | JsonValue.Array   (a) ->
            yield! a
            |> Seq.collect (expander "arrayItem")
    }

Frame.CustomExpanders.Add(typeof<JsonDocument>,
                          fun o -> (o :?> JsonDocument).JsonValue |> expander "root")

Frame.CustomExpanders.Add(typeof<JsonValue>,
                          fun o -> o :?> JsonValue |> expander "root")

let info =
    JsonValue.Parse(""" { "name": "Tomas", "born": 1985 } """)

let df =
    [ series ["It" => info] ]
    |> Frame.ofRowsOrdinal

let dfexpanded = Frame.expandAllCols 2 df

这给了我一些我不知道如何解释的东西,但不是预期的结果:

It.properties                                         It.Tag It.IsString It.IsNumber It.IsFloat It.IsRecord It.IsArray It.IsBoolean It.IsNull It._Print                             
0 -> System.Tuple`2[System.String,FSharp.Data.JsonValue][] 3      False       False       False      True        False      False        False     { "name": "Tomas", "born": 1985 } 

感谢您的任何意见!

【问题讨论】:

    标签: json f#-data deedle


    【解决方案1】:

    问题似乎是数据框中It的类型不是JsonValue,而是编译器生成的子类之一,用于表示可区分联合的个别情况——在这种特殊情况下,一个名为 JsonValue+Record 的嵌套类型。

    Deedle 会寻找精确的类型匹配(并且不会尝试为基类查找扩展器),因此解决方法是为每个嵌套类注册扩展器:

    for t in typeof<JsonValue>.GetNestedTypes() do
      Frame.CustomExpanders.Add(t, fun o -> o :?> JsonValue |> expander "root")
    

    运行后,您的代码给出了预期的结果:

    val dfexpanded : Frame<int,string> =
    
         It.name It.born 
    0 -> Tomas   1985    
    

    【讨论】:

    • 一如既往的快速准确 :) 谢谢!
    • 额外问题 ;) 你是如何诊断这个问题的?我不知道如何调查这个......(当然我是一个 F# 菜鸟,所以这没什么好说的)
    • @sebhofer 好问题!好吧,您在输出中看到的扩展属性看起来就像 .NET 表示 JsonValue 所具有的属性。这表明您的扩展器被忽略了(即使我在那里没有看到任何问题)。我也觉得在处理 Deedle 时,我们没有对带有扩展器的基本类型做任何聪明的事情 :-) 所以我认为这很可能是因为类型不完全匹配......(对不起,这不是很可重复使用的方法!)
    • 好吧,至少它让我安心(......这对我来说是一个很难诊断的问题......)再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多