如何才能更快地进行此 reshape 并占用更少的内存?我的目标是使用 4 Gb RAM reshape 500,000 行 x 500 列的数据帧。
这是一个可以生成一些可重现数据的函数:
make_example <- function(ndoc, ntop){
# doc numbers
V1 = seq(1:ndoc)
# filenames
V2 <- list("vector", size = ndoc)
for (i in 1:ndoc){
V2[i] <- paste(sample(c(rep(0:9,each=5),LETTERS,letters),5,replace=TRUE),collapse='')
}
# topic proportions
tvals <- data.frame(matrix(runif(1:(ndoc*ntop)), ncol = ntop))
# topic number
tnumvals <- data.frame(matrix(sample(1:ntop, size = ndoc*ntop, replace = TRUE), ncol = ntop))
# now make topic props and topic numbers alternating columns (rather slow!)
alternating <- data.frame(c(matrix(c(tnumvals, tvals), 2, byrow = T)) )
# make colnames for topic number and topic props
ntopx <- sapply(1:ntop, function(j) paste0("ntop_",j))
ptopx <- sapply(1:ntop, function(j) paste0("ptop_",j))
tops <- c(rbind(ntopx,ptopx))
# make data frame
dat <- data.frame(V1 = V1,
V2 = unlist(V2),
alternating)
names(dat) <- c("docnum", "filename", tops)
# give df as result
return(dat)
}
制作一些可重现的数据:
set.seed(007)
dat <- make_example(500000, 500)
这是我当前的方法(感谢 https://stackoverflow.com/a/8058714/1036500 ):
library(reshape2)
NTOPICS = (ncol(dat) - 2 )/2
nam <- c('num', 'text', paste(c('topic', 'proportion'), rep(1:NTOPICS, each = 2), sep = ""))
system.time( dat_l2 <- reshape(setNames(dat, nam), varying = 3:length(nam), direction = 'long', sep = ""))
system.time( dat.final2 <- dcast(dat_l2, dat_l2[,2] ~ dat_l2[,3], value.var = "proportion" ) )
一些时间,仅用于 reshape
,因为这是最慢的步骤:
make_example(5000,100)
= 82 秒
make_example(50000,200)
= 2855 秒(尝试第二步时崩溃)
make_example(500000,500)
= 尚不可能...
还有哪些其他方法可以更快且占用更少的内存来进行此 reshape (data.table
、this)?
最佳答案
我非常怀疑在传递 500000 x 500 数据帧时,用那么少量的 RAM 是否会成功。我想知道在有限的空间里你是否可以做哪怕是简单的 Action 。购买更多内存。此外,reshape2 很慢,所以使用 stats::reshape 来处理大的东西。并给出有关分隔符是什么的提示。
> set.seed(007)
> dat <- make_example(5, 3)
> dat
docnum filename ntop_1 ptop_1 ntop_2 ptop_2 ntop_3 ptop_3
1 1 y8214 3 0.06564574 1 0.6799935 2 0.8470244
2 2 e6x39 2 0.62703876 1 0.2637199 3 0.4980761
3 3 34c19 3 0.49047504 3 0.1857143 3 0.7905856
4 4 1H0y6 2 0.97102441 3 0.1851432 2 0.8384639
5 5 P6zqy 3 0.36222085 3 0.3792967 3 0.4569039
> reshape(dat, direction="long", varying=3:8, sep="_")
docnum filename time ntop ptop id
1.1 1 y8214 1 3 0.06564574 1
2.1 2 e6x39 1 2 0.62703876 2
3.1 3 34c19 1 3 0.49047504 3
4.1 4 1H0y6 1 2 0.97102441 4
5.1 5 P6zqy 1 3 0.36222085 5
1.2 1 y8214 2 1 0.67999346 1
2.2 2 e6x39 2 1 0.26371993 2
3.2 3 34c19 2 3 0.18571426 3
4.2 4 1H0y6 2 3 0.18514322 4
5.2 5 P6zqy 2 3 0.37929675 5
1.3 1 y8214 3 2 0.84702439 1
2.3 2 e6x39 3 3 0.49807613 2
3.3 3 34c19 3 3 0.79058557 3
4.3 4 1H0y6 3 2 0.83846387 4
5.3 5 P6zqy 3 3 0.45690386 5
> system.time( dat <- make_example(5000,100) )
user system elapsed
2.925 0.131 3.043
> system.time( dat2 <- reshape(dat, direction="long", varying=3:202, sep="_"))
user system elapsed
16.766 8.608 25.272
我想说,在这个过程中使用了 32 GB 内存总量的大约 1/5,这比您的目标小 250 倍,所以您的机器挂起我并不感到惊讶。 (它不应该“崩溃”。 R 的作者希望您提供行为的准确描述,并且我怀疑 R 进程在分页到虚拟内存中时停止响应。)我遇到了性能问题,需要使用 700 万条记录 x 100 列的数据集来解决使用 32 GB 时。
关于用更少的时间和更少的内存 reshape 交替的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16494665/