超大数据集重塑方法选型验证与技术疑问解答
超大数据集长转宽:reshape vs 现代化工具的性能对决
咱在处理超大数据集的时候,最头疼的就是计算慢还容易崩溃,所以选对数据重塑方法真的太关键了。现在像data.table::dcast、tidyr::spread这些现代化工具的性能都已经优化得很不错了,尤其是dcast.data.table,速度快得离谱,这就让base R里的reshape在常规基准测试里看起来有点过时甚至没用。但最近有不少声音说,在处理那种超出内存的超大数据集时,reshape反而无可替代,而且不少崩溃报告也印证了这一点。
实验设计与数据示例
为了验证这个说法,我做了一组实验:基于不同大小的模拟数据集(逐步耗尽8GB内存),对比reshape、dcast、dcast.data.table、spread四种长转宽方法的性能,每种方法只跑3次测试。
实验用的数据集长这样:
> head(df1, 3) id tms y 1 1 1970-01-01 01:00:01 0.7463622 2 2 1970-01-01 01:00:01 0.1417795 3 3 1970-01-01 01:00:01 0.6993089
实验结果
跑出来的结果挺有意思:
- 小数据场景下,
dcast.data.table绝对是速度王者,始终最快; - 当数据集达到8GB时,
dcast、dcast.data.table、spread全都因为内存耗尽直接崩溃,只有reshape能撑着跑完,但速度慢得让人抓狂。
初步结论与待解疑问
基于这个结果,我先得出了个初步结论:dcast和spread适合处理能塞进内存、或者计算过程不会把内存耗干的数据集;真遇到超大数据集,可能只能靠reshape撑着。但这里还有几个没搞明白的技术问题:
- 这个初步结论到底站不站得住脚?有没有例外情况?
data.table和tidyr的方法为啥会在超大数据集上崩溃?它们和reshape在实现逻辑上到底有啥不一样?- 处理超大数据集真的只有
reshape这一个可靠但慢得离谱的选择吗? - 像
tapply、unstack、xtabs这些没测的方法表现咋样?有没有比reshape更快的替代方案?
实验代码(8GB数据集版本)
以下是生成8GB数据集并测试的代码,提醒一句:运行起来耗时很长,谨慎尝试!
# 8GB版本 n <- 1e3 t1 <- 2.15e5 # 调整这个值可以逐步让数据集超出内存,当前约8GB df1 <- expand.grid(id=1:n, tms=as.POSIXct(1:t1, origin="1970-01-01")) df1$y <- rnorm(nrow(df1)) dim(df1) # [1] 450000000 3 > head(df1, 3) id tms y 1 1 1970-01-01 01:00:01 0.7463622 2 2 1970-01-01 01:00:01 0.1417795 3 3 1970-01-01 01:00:01 0.6993089 object.size(df1) # 9039666760 bytes library(data.table) DT1 <- as.data.table(df1) library(microbenchmark) library(tidyr) # 注意:运行耗时较长! mbk <- microbenchmark(reshape=reshape(df1, idvar="tms", timevar="id", direction="wide"), dcast=dcast(df1, tms ~ id, value.var="y"), dcast.dt=dcast(DT1, tms ~ id, value.var="y"), tidyr=spread(df1, id, y), times=3L)
内容的提问来源于stack exchange,提问作者jay.sf
相关产品推荐
相关产品推荐

