gpt4 book ai didi

performance - R:加速 "group by"操作

转载 作者:行者123 更新时间:2023-12-03 07:46:14 25 4
gpt4 key购买 nike

我有一个模拟,中间有一个巨大的聚合和组合步骤。我使用 plyr 的 ddply() 函数对这个过程进行了原型(prototype)设计,它可以很好地满足我的大部分需求。但我需要更快的聚合步骤,因为我必须运行 10K 次模拟。我已经在并行扩展模拟,但如果这一步骤更快,我可以大大减少所需的节点数量。

这是我想要做的事情的合理简化:

library(Hmisc)

# Set up some example data
year <- sample(1970:2008, 1e6, rep=T)
state <- sample(1:50, 1e6, rep=T)
group1 <- sample(1:6, 1e6, rep=T)
group2 <- sample(1:3, 1e6, rep=T)
myFact <- rnorm(100, 15, 1e6)
weights <- rnorm(1e6)
myDF <- data.frame(year, state, group1, group2, myFact, weights)

# this is the step I want to make faster
system.time(aggregateDF <- ddply(myDF, c("year", "state", "group1", "group2"),
function(df) wtd.mean(df$myFact, weights=df$weights)
)
)

感谢所有提示或建议!

最佳答案

您可以使用不可变数据帧,而不是普通的 R 数据帧,它在子集化时返回指向原始数据的指针,并且速度更快:

idf <- idata.frame(myDF)
system.time(aggregateDF <- ddply(idf, c("year", "state", "group1", "group2"),
function(df) wtd.mean(df$myFact, weights=df$weights)))

# user system elapsed
# 18.032 0.416 19.250

如果我要编写一个专门针对这种情况定制的 plyr 函数,我会这样做:

system.time({
ids <- id(myDF[c("year", "state", "group1", "group2")], drop = TRUE)
data <- as.matrix(myDF[c("myFact", "weights")])
indices <- plyr:::split_indices(seq_len(nrow(data)), ids, n = attr(ids, "n"))

fun <- function(rows) {
weighted.mean(data[rows, 1], data[rows, 2])
}
values <- vapply(indices, fun, numeric(1))

labels <- myDF[match(seq_len(attr(ids, "n")), ids),
c("year", "state", "group1", "group2")]
aggregateDF <- cbind(labels, values)
})

# user system elapsed
# 2.04 0.29 2.33

它的速度要快得多,因为它避免了复制数据,只在计算时提取每个计算所需的子集。将数据转换为矩阵形式可以进一步提高速度,因为矩阵子集比数据帧子集要快得多。

关于performance - R:加速 "group by"操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3685492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com