You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia中高效计算多列百分比变化的方法

Julia DataFrame 批量分组计算多列百分比变化

给定如下示例DataFrame,需要按id分组,计算每组内指定列(实际场景有50列)的百分比变化:

using DataFrames, Dates

# 示例数据
df = DataFrame(
    id = [1, 1, 2, 2, 3, 3],
    filing_date = Date.(["2022-01-01", "2022-02-01", "2022-01-10", "2022-02-20", "2022-01-15", "2022-03-01"]),
    col1 = [100, 110, 200, 220, 50, 55],
    col2 = [1000, 1050, 2000, 2100, 500, 525]
)

原方案仅支持单列处理,需合并多个结果表,效率低下。以下是两种高效的批量处理方案:

方案一:自定义批量处理函数 + 单次分组计算

直接定义可处理多列的分组函数,一次性完成所有列的计算,避免多次分组和合并操作:

# 定义批量计算百分比变化的函数
function percent_change_group(gdf::SubDataFrame, target_cols::Vector{Symbol})
    sort!(gdf, :filing_date, rev=true)
    if nrow(gdf) < 2
        # 组内不足两行时,所有列返回missing
        return DataFrame([Symbol(col, "_change") => [missing] for col in target_cols])
    end
    # 计算每列的百分比变化
    changes = [(gdf[1, col] - gdf[2, col]) / gdf[2, col] * 100 for col in target_cols]
    return DataFrame([Symbol(col, "_change") => [val] for (col, val) in zip(target_cols, changes)])
end

# 指定需要处理的列(排除id和filing_date)
target_cols = setdiff(names(df), [:id, :filing_date])

# 分组计算并生成结果
result = combine(groupby(df, :id), gdf -> percent_change_group(gdf, target_cols))

方案二:transform + lag 链式处理

利用lag函数获取每组内的前一行数据,结合分组过滤得到最终结果,逻辑更直观:

# 指定目标列
target_cols = setdiff(names(df), [:id, :filing_date])

# 链式操作完成排序、滞后值计算、变化率计算
using DataFramesMeta

result = @chain df begin
    groupby(:id)
    @transform begin
        # 每组内按filing_date降序排序
        sort!(:filing_date, rev=true)
        # 为每个目标列生成滞后值(前一行数据)
        $(Symbol.(target_cols, "_prev")) = lag.(cols(target_cols), 1)
    end
    groupby(:id)
    @combine begin
        if nrow(_) < 2
            # 组内不足两行时返回missing
            $(Symbol.(target_cols, "_change")) .= missing
        else
            # 计算百分比变化
            $(Symbol.(target_cols, "_change")) = (cols(target_cols)[1] .- cols(Symbol.(target_cols, "_prev"))[1]) ./ cols(Symbol.(target_cols, "_prev"))[1] .* 100
        end
    end
end

验证结果

两种方案均会生成符合预期的结果:

Row │ id     col1_change  col2_change
     │ Int64  Float64?     Float64?
─────┼──────────────────────────────────
   1 │     1         10.0          5.0
   2 │     2         10.0          5.0
   3 │     3         10.0          5.0

内容的提问来源于stack exchange,提问作者IsThere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:33:10