【问题标题】:Groupby with sum on Julia DataframeGroupby 与 Julia Dataframe 上的总和
【发布时间】:2025-12-01 13:25:01
【问题描述】:

我正在尝试对具有 Int 和 String 值的 Julia 数据框进行 groupby + sum

例如,df :

│ Row │ A      │ B      │ C     │ D      │
│     │ String │ String │ Int64 │ String │
├─────┼────────┼────────┼───────┼────────┤
│ 1   │ x1     │ a      │ 12    │ green  │
│ 2   │ x2     │ a      │ 7     │ blue   │
│ 3   │ x1     │ b      │ 5     │ red    │
│ 4   │ x2     │ a      │ 4     │ blue   │
│ 5   │ x1     │ b      │ 9     │ yellow │

要在 Python 中执行此操作,命令可以是:

df_group = df.groupby(['A', 'B']).sum().reset_index()

我将获得以下带有初始列标签的输出结果:

    A  B   C
0  x1  a  12
1  x1  b  14
2  x2  a  11

我想在 Julia 中做同样的事情。我试过这种方式,不成功:

df_group = aggregate(df, ["A", "B"], sum)

MethodError: 没有方法匹配 +(::String, ::String)

您知道在 Julia 中执行此操作的方法吗?

【问题讨论】:

    标签: dataframe group-by julia aggregate


    【解决方案1】:

    尝试(实际上不是非字符串列,可能您想要数字列):

    numcols = names(df, findall(x -> eltype(x) <: Number, eachcol(df)))
    combine(groupby(df, ["A", "B"]), numcols .=> sum .=> numcols)
    

    如果您想允许 missing 值(并在求和时跳过它们),那么:

    numcols = names(df, findall(x -> eltype(x) <: Union{Missing,Number}, eachcol(df)))
    combine(groupby(df, ["A", "B"]), numcols .=> sum∘skipmissing .=> numcols)
    

    【讨论】:

    • 感谢您的回答。在实践中,我的真实数据框有很多列要求和(+100)。所以我想找到一种更通用的方法。这是否可以对所有非字符串列求和?
    • 在 master 上是可能的(所以它将在 0.22 版本中可用)。我将使用现在可以使用的建议来更新答案。
    【解决方案2】:

    Julia DataFrames 支持split-apply-combine 逻辑,类似于pandas,所以聚合看起来像

    using DataFrames
    
    df = DataFrame(:A => ["x1", "x2", "x1", "x2", "x1"], 
                   :B => ["a", "a", "b", "a", "b"],
                   :C => [12, 7, 5, 4, 9],
                   :D => ["green", "blue", "red", "blue", "yellow"])
    
    gdf = groupby(df, [:A, :B])
    combine(gdf, :C => sum)
    

    结果

    julia> combine(gdf, :C => sum)
    3×3 DataFrame
    │ Row │ A      │ B      │ C_sum │
    │     │ String │ String │ Int64 │
    ├─────┼────────┼────────┼───────┤
    │ 1   │ x1     │ a      │ 12    │
    │ 2   │ x2     │ a      │ 11    │
    │ 3   │ x1     │ b      │ 14    │
    

    您可以在Pipe.jlUnderscores.jl 的帮助下跳过gdf 的创建

    using Underscores
    
    @_ groupby(df, [:A, :B]) |> combine(__, :C => sum)
    

    您可以使用以下语法为新列命名

    julia> @_ groupby(df, [:A, :B]) |> combine(__, :C => sum => :C)
    3×3 DataFrame
    │ Row │ A      │ B      │ C     │
    │     │ String │ String │ Int64 │
    ├─────┼────────┼────────┼───────┤
    │ 1   │ x1     │ a      │ 12    │
    │ 2   │ x2     │ a      │ 11    │
    │ 3   │ x1     │ b      │ 14    │
    

    【讨论】:

    • 感谢您的回答。
    • 如果我想在同一行中进行分组求和和计数怎么办?