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

如何借助data.table加速分组值的归一化处理

data.table分组缩放计算的速度优化问题

我正在尝试加速对data.table对象的特定计算。该表包含一个value列和一个或多个分组列,需求是:对每个分组组合,若组内value的总和大于1,就按比例缩小这些值,使其总和变为1;若总和不大于1,则保持原值不变。可以假设所有value均为非负。

示例数据设置(50万行)

library(data.table)

n_rows <- 5e5

dt <- data.table(
  # 分组变量
  group1 = sample(letters, size = n_rows, replace = TRUE),
  group2 = sample(letters, size = n_rows, replace = TRUE),
  group3 = sample(letters, size = n_rows, replace = TRUE),
  group4 = sample(letters, size = n_rows, replace = TRUE),
  # 非负数值列
  value  = runif(n_rows)
)

初始解决方案

scale_values <- function(values) {
  values / sum(values)
}

dt[, {value := if (sum(value) > 1) {
                 scale_values(value)
               } else {
                 value
               }}, 
   by = list(group1, group2, group3, group4)]

这是我尝试多种data.table语法和scale_values替代实现后找到的最快方案,但实际场景中数据表会有约2000万行数据和5个分组列,希望能进一步提升速度。

补充:两步法优化

后来发现分两步处理的速度快得多:

dt[, sum_values := sum(value), by = list(group1, group2, group3, group4)][
   sum_values > 1, value := scale_values(value), by = list(group1, group2, group3, group4)]

但我不太清楚这种两步法速度更快的原因,希望能得到解释。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:30:54