【发布时间】:2021-08-12 20:44:20
【问题描述】:
在 DataFrames.jl 中表达汇总聚合的简洁方式是什么?
示例数据集:
+---+----------+-----+---------+------+
| id| date_col|group| item|amount|
+---+----------+-----+---------+------+
| 1|2020-03-11| A|BOO00OXXX| 1.0|
| 2|2020-03-11| A|BOO00OXXY| 2.0|
| 3|2020-03-11| B|BOO00OXXZ| 17.0|
| 4|2020-03-12| B|BOO00OXXA| 9.0|
| 5|2020-03-12| B|BOO00OXXB| 1.0|
| 6|2020-03-12| B|BOO00OXXY| 5.0|
| 7|2020-03-13| C|BOO00OXXY| 2.0|
| 8|2020-03-13| C|BOO00OXXX| 1.0|
| 9|2020-03-13| C|BOO00OXXY| 2.0|
+---+----------+-----+---------+------+
# desired output
+------+---------+
|group |total_amt|
+------+---------+
|ROLLUP| 40.0|
| A | 3.0|
| B | 32.0|
| C | 5.0|
+------+---------+
我通常需要汇总一个数据集,有时用于共享报告,该报告通过小计和总计汇总某些列的值。这些在 Excel 中称为“汇总”或“小计”/“总计”。
在 Spark 中,这些是通过 rollup 或 cube 聚合方便地生成的。上面的结果是通过以下 spark api 调用生成的。
如何使用 Julia DataFrames.jl 生成类似的表格?
// scala spark
df.rollup("group")
.agg(sum("amount").as("total_amt"))
.orderBy("group")
.show()
+-----+---------+
|group|total_amt|
+-----+---------+
| null| 40.0|
| A| 3.0|
| B| 32.0|
| C| 5.0|
+-----+---------+
// note the aggregated column label is null for the subtotal (aka rollup)
注意:我可以使用多个 julia groupby() 和 combine() 操作生成结果,然后将结果合并或 vcat 到单个数据帧中。我需要并且想要一个简洁易读的成语。
编辑:添加一个特定的 julia 实现来说明为什么我想要更简洁的东西。
using DataFrames, Dates
df = DataFrame(id = [1,2,3,4,5,6,7,8,9]
, date_col = Date.(["2020-03-11","2020-03-11","2020-03-11","2020-03-12","2020-03-12","2020-03-12","2020-03-13","2020-03-13","2020-03-13"])
, group = ["A","A","B","B","B","B","C","C","C"]
, amount = [1.0,2.0,17.0,9.0,1.0,5.0,2.0,1.0,2.0]
)
# replicate the spark.rollup example
df1 = combine(groupby(_, :group), :amount => sum => :total_amt);
df2 = combine(df, :amount => sum => :total_amt);
df2[:, :group] = [missing];
df_result = sort(vcat(df1, df2, cols = :setequal), rev = true)
4×2 DataFrame
Row │ group total_amt
│ String? Float64
─────┼────────────────────
1 │ missing 40.0
2 │ C 5.0
3 │ B 32.0
4 │ A 3.0
添加@bkamins 答案的版本,坚持使用combine()
到目前为止,我认为我更喜欢这个答案,因为它保持了一点对称性,并且如果将其制成一个函数,则更容易看到参数的去向。
using Chain
@chain df begin
groupby(:group)
combine(:amount => sum => :total_amt)
append!(insertcols!(combine(df, :amount => sum => :total_amt), :group => "ROLLUP"))
sort(:total_amt, rev = true)
end
【问题讨论】:
标签: dataframe julia dataframes.jl