我可以在 Julia 中 "group by" 一组字典吗?

Can I "group by" an array of dictionaries in Julia?

我正在从 JSON 文件中读取一个数组,因为在将其转换为 DataFrame 以进行进一步操作之前,我需要对其执行归约。为了争论,假设就是这样

a = [Dict("A" => 1, "B" => 1, "C" => "a")
     Dict("A" => 1, "B" => 2, "C" => "b")
     Dict("A" => 2, "B" => 1, "C" => "b")
     Dict("A" => 2, "B" => 2, "C" => "a")]

现在,如果我可以按一个或多个键(比如 A 和 C)对数组进行分组,对每个组执行更简单的归约,然后将行重新组合成更大的 Dict 数组,然后我可以轻松地将其转换为 DataFrame.

一个解决方案是将其变成 DataFrame,将其分成组,将各个组变成矩阵,进行归约(有一些困难,因为现在我已经失去了引用的能力元素的名称),将简化后的矩阵转回 (Sub?)DataFrames(由于名称的原因,难度更大),并希望它们能很好地组合成一个巨大的 DataFrame.

有没有更简单 and/or 更实用的方法?

EDIT 在有人建议我查看 Query.jl 之前,reduce 我是 运行 returns 一个数组,行数较少因为我正在压缩某些后续行。如果我可以用 Query.jl 做这样的事情,有人可以提示如何做吗,因为文档并不完全清楚如何 "aggregate" 没有 return 单个值的任何东西.示例:

 A   B   C
-----------
 1       a
 2   1   a
 3       b
 4   2   b

应该按 "C" 分组并将 table 变成类似

的东西
 A   B   C
-----------
 1   1   a
 3   2   b

澄清一下,reduce 正在工作,我只是想通过在压缩之前不必检查一行是否属于前一行的同一组来简化它。

它仍处于实验阶段,但 SplitApplyCombine.jl 可能会成功。您可以使用您想要的任何键函数对任意可迭代对象进行分组,并在最后得到一个键 -> group dict。

julia> ## Pkg.clone("https://github.com/JuliaData/SplitApplyCombine.jl.git")

julia> using SplitApplyCombine

julia> group(x->x["C"], a)
Dict{Any,Array{Dict{String,Any},1}} with 2 entries:
  "b" => Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("B", 2),Pair{String,Any}("A", 1),Pair{String,Any}("C", "b")), Dict{String,Any}(Pair{String,Any}("…
  "a" => Dict{String,Any}[Dict{String,Any}(Pair{String,Any}("B", 1),Pair{String,Any}("A", 1),Pair{String,Any}("C", "a")), Dict{String,Any}(Pair{String,Any}("…

然后您可以使用标准 [map]reduce 操作(这里使用 SAC @_ 宏进行管道):

julia> @_ a |> group(x->x["C"], _) |> values(_) |> reduce(vcat, _)
4-element Array{Dict{String,Any},1}:
 Dict{String,Any}(Pair{String,Any}("B", 2),Pair{String,Any}("A", 1),Pair{String,Any}("C", "b"))
 Dict{String,Any}(Pair{String,Any}("B", 1),Pair{String,Any}("A", 2),Pair{String,Any}("C", "b"))
 Dict{String,Any}(Pair{String,Any}("B", 1),Pair{String,Any}("A", 1),Pair{String,Any}("C", "a"))
 Dict{String,Any}(Pair{String,Any}("B", 2),Pair{String,Any}("A", 2),Pair{String,Any}("C", "a"))