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

如何加速data.table按列迭代并实现基于指定列均值的向量化解法

优化data.table列运算:避免循环创建小表的高效向量化方案

你提到的问题确实戳中了原方法的性能瓶颈——每次循环里创建新的data.table会带来大量不必要的内存和计算开销,尤其是当数据集规模较大时,这种开销会被放大。我们可以利用data.table的原生向量化特性,用更高效的方式实现需求。

核心思路

先一次性计算出am == 1时目标列的均值,再直接用这些均值对原列做批量除法运算,全程不需要循环创建小表。

具体实现代码

require(data.table)
dt = data.table(mtcars)
cols = c('mpg', 'hp', 'disp')

# 第一步:一次性计算am==1时各目标列的均值
mean_am1 = dt[am == 1, lapply(.SD, mean, na.rm = TRUE), .SDcols = cols]

# 第二步:用向量化方式批量更新列
dt[, (cols) := Map(`/`, .SD, mean_am1), .SDcols = cols]

print(dt)

为什么这个方法更快?

  1. 避免冗余对象创建:原方法每次循环都要新建一个小data.table,这涉及到内存分配、数据拷贝等操作,而优化后的方法只计算一次均值,后续直接对整列做向量化运算。
  2. 利用data.table的列操作优势:data.table的.SD和赋值操作都是针对列级别的优化,向量化运算的效率远高于逐行/逐循环的操作。
  3. 代码更简洁易读:不需要额外定义specificMean函数,逻辑更直观,也更容易维护。

另一种等价写法(更贴近你原代码的风格)

如果你习惯用lapply的写法,也可以这样实现:

dt[, (cols) := lapply(cols, function(col) {
  dt[[col]] / mean_am1[[col]]
})]

这种写法同样是向量化的,效率和Map版本一致,只是语法风格不同。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:18:09