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

处理百万级区间时如何加速dplyr::between的执行?

高效统计区间内异常值数量

你有一个包含起始列X1和结束列X2的数据框,还有一个异常值列表,需要统计每个区间内落入的异常值数量。原代码用for循环实现,但面对百万行数据时效率极低,以下是几种优化方案:

原代码回顾

library("dplyr")

set.seed(2022)

dat = data.frame(matrix(sort(sample(1:500, 50)), ncol = 2, byrow = T))
colnames(dat) <- c("X1", "X2")
dat$Outliers = NA

outliers = sort(sample(1:500, 30))

for (i in 1:25){
  dat$Outliers[i] = length(which(between(outliers, dat$X1[i], dat$X2[i]) == T))
}

优化方案1:基础R二分查找(最快)

因为outliers已排序,用findInterval快速定位区间上下限在异常值中的位置,位置差即为区间内异常值数量,完全向量化操作,无循环:

# 若真实数据中outliers未排序,先执行 outliers <- sort(outliers)
lower_pos <- findInterval(dat$X1, outliers, rightmost.closed = TRUE)
upper_pos <- findInterval(dat$X2, outliers, rightmost.closed = TRUE)
dat$Outliers <- upper_pos - lower_pos

优化方案2:data.table非等值连接

data.table的非等值连接在百万级数据集上效率优异,适合复杂数据场景:

library(data.table)

# 转换为data.table格式
setDT(dat)
outliers_dt <- data.table(val = outliers)

# 非等值连接并按区间计数
dat[, Outliers := outliers_dt[.SD, on = .(val >= X1, val <= X2), .N, by = .EACHI]$N]

优化方案3:dplyr+向量化操作

若偏好dplyr语法,用purrr::map2配合向量化判断,效率远高于for循环:

library(dplyr)
library(purrr)

dat <- dat %>%
  mutate(Outliers = map2_dbl(X1, X2, ~sum(between(outliers, .x, .y))))

方案对比

  • 基础R二分查找:速度最快、内存占用最低,优先推荐
  • data.table非等值连接:大数据集下表现稳定,适配复杂数据逻辑
  • dplyr+map2:语法简洁,但百万行数据下效率略逊于前两者

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 19:09:22