gpt4 book ai didi

r - 将 data.table 拆分为大致相等的部分

转载 作者:行者123 更新时间:2023-12-04 11:56:11 24 4
gpt4 key购买 nike

要并行化任务,我需要将大 data.table 拆分为大致相等的部分,
将通过列定义的组保持在一起,id .认为:
N是数据的长度
kid 的不同值的数量
M是所需零件的数量

这个想法是 M << k << N,所以 split 为 id不好。

library(data.table)
library(dplyr)

set.seed(1)
N <- 16 # in application N is very large
k <- 6 # in application k << N
dt <- data.table(id = sample(letters[1:k], N, replace=T), value=runif(N)) %>%
arrange(id)
t(dt$id)

# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
# [1,] "a" "b" "b" "b" "b" "c" "c" "c" "d" "d" "d" "e" "e" "f" "f" "f"

在此示例中, M=3 的所需拆分是 {{a,b}, {c,d}, {e,f}}M=4{{a,b}, {c}, {d,e}, {f}}
更一般地,如果 id 是数字,截止点应该是 quantile(id, probs=seq(0, 1, length.out = M+1), type=1)或一些类似的分割成大致相等的部分。

什么是有效的方法来做到这一点?

最佳答案

初步评论
我推荐阅读什么 the main author of data.table has to say关于与它的并行化。
我不知道你对data.table有多熟悉,但你可能忽略了它的by争论...?从下面引用@eddi 的评论...

Instead of literally splitting up the data - create a new "parallel.id" column, and then call

dt[, parallel_operation(.SD), by = parallel.id] 


回答,假设您不想使用 by
按大小对 ID 进行排序:
ids   <- names(sort(table(dt$id)))
n <- length(ids)
重新排列,以便我们在大 ID 和小 ID 之间交替, following Arun's interleaving trick :
alt_ids <- c(ids, rev(ids))[order(c(1:n, 1:n))][1:n]
按顺序拆分 id,每个组中的 ID 数量大致相同(如 zero323's answer ):
gs  <- split(alt_ids, ceiling(seq(n) / (n/M)))

res <- vector("list", M)
setkey(dt, id)
for (m in 1:M) res[[m]] <- dt[J(gs[[m]])]
# if using a data.frame, replace the last two lines with
# for (m in 1:M) res[[m]] <- dt[id %in% gs[[m]],]
检查尺寸是否太差:
# using the OP's example data...

sapply(res, nrow)
# [1] 7 9 for M = 2
# [1] 5 5 6 for M = 3
# [1] 1 6 3 6 for M = 4
# [1] 1 4 2 3 6 for M = 5
虽然我强调 data.table在顶部,这应该适用于 data.frame , 也。

关于r - 将 data.table 拆分为大致相等的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32125795/

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