gpt4 book ai didi

r - 在 R 中拆分的快速替代方案

转载 作者:行者123 更新时间:2023-12-04 03:27:55 27 4
gpt4 key购买 nike

我正在使用 split() 对数据框进行分区为了使用parLapply()并行调用每个分区上的函数。数据框有 130 万行和 20 列。我按两列拆分/分区,都是字符类型。看起来有 ~47K 唯一 ID 和 ~12K 唯一代码,但并非每个 ID 和代码配对都匹配。结果分区数约为 250K。这是split()线:

 system.time(pop_part <- split(pop, list(pop$ID, pop$code)))

然后分区将被送入 parLapply()如下:
cl <- makeCluster(detectCores())
system.time(par_pop <- parLapply(cl, pop_part, func))
stopCluster(cl)

我已经让 split()单独的代码运行了将近一个小时,而且还没有完成。我可以单独按 ID 拆分,这需要大约 10 分钟。此外,R studio 和工作线程消耗了大约 6GB 的 RAM。

我知道结果分区数的原因是我在 Pentaho 数据集成 (PDI) 中有等效的代码,它在 30 秒内运行(对于整个程序,而不仅仅是“拆分”代码)。我不希望 R 能有那种表现,但最坏的情况可能会在 10 - 15 分钟内完成。

主要问题:有没有更好的分割替代方案?我也试过 ddply().parallel = TRUE ,但它也跑了一个多小时,一直没有完成。

最佳答案

将索引拆分为 pop

idx <- split(seq_len(nrow(pop)), list(pop$ID, pop$code))

拆分并不慢,例如,
> system.time(split(seq_len(1300000), sample(250000, 1300000, TRUE)))
user system elapsed
1.056 0.000 1.058

所以如果你是我猜你的数据的某些方面会减慢速度,例如, IDcode都是具有多个水平的因素,因此计算它们的完整交互作用,而不是数据集中出现的水平组合
> length(split(1:10, list(factor(1:10), factor(10:1))))
[1] 100
> length(split(1:10, paste(letters[1:10], letters[1:10], sep="-")))
[1] 10

或者你的内存不足。

使用 mclapply而不是 parLapply如果您在非 Windows 机器上使用进程(我猜是这种情况,因为您要求 detectCores() )。
par_pop <- mclapply(idx, function(i, pop, fun) fun(pop[i,]), pop, func)

从概念上讲,您的目标似乎是 pvec (在处理器上分配矢量化计算)而不是 mclapply (迭代数据框中的各个行)。

此外,作为第一步,考虑确定 func 中的瓶颈。 ;数据很大但不是那么大,所以也许不需要并行评估——也许你写的是 PDI 代码而不是 R 代码?注意数据框中的数据类型,例如因子与字符。在编写不佳的 R 代码和高效的 R 代码之间获得 100 倍的加速并不罕见,而并行评估最多与内核数量成正比。

关于r - 在 R 中拆分的快速替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19038140/

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