【问题标题】:R - Expected speed of do.call(rbind,...)R - do.call(rbind,...) 的预期速度
【发布时间】:2018-09-08 23:58:26
【问题描述】:

我有一个名为 prebindgames 的列表,其中包含超过 200 万个条目。每个列表条目是一个有 6 列的单行数据框。为了了解每列中数据的类型,每个数据框的形式如下:

data.frame(Time = double(),
           HScore = numeric(),
           AScore = numeric(),
           HTeam = character(),
           ATeam = character(),
           GameID = character(),
           stringsAsFactors = FALSE)

数字列不超过千位,字符列不超过 10 个字符。我尝试运行do.call(rbind, prebindgames),它运行了一夜,没有停止的迹象。我再次尝试了一些较小的值:

start_time <- Sys.time()
allgamespbp <- do.call(rbind, prebindgames[1:1000]) 
end_time <- Sys.time()
print(end_time - start_time)
Time difference of 1.059694 secs

prebindgames[1:10000]
Time difference of 11.00168 secs

prebindgames[1:20000]
Time differences of 37.30913 secs

所以我已经看到一些指数级的增长,这可以解释为什么在一次调用中绑定所有 200 万时事情会失控。所以我的三个问题是:

1) 这正常吗?如果我的预期速度基于一个有 10000 个条目的列表,那么 200 万个条目只需要大约 40 分钟

2) 我可以做些什么来加快这个过程?据我所知,替换设置长度列表中的值然后使用 do.call 是将行绑定在一起的最有效方法。

3) 如果在不对代码或设备进行重大更改的情况下以合理的速度获得它,我可以修改它以查看我的进度吗?

背景:这是一个网络爬虫项目,我将把许多 NBA 比赛的得分合并到一张大表中。完整的代码可以在这里找到:https://github.com/NicholasHassan/NBAComeback

如果您对此感到好奇,可以跳到NBA Comeback.R 的第54 行并使用pbpurls.csv 来查看抓取过程是什么样的。

【问题讨论】:

  • 你没有错。当我对 100 列和 1000 列做了一个简单的实验时,似乎ncol^2 在预测rbinding 的执行时间方面很重要(ncol 是列数),表明存在非线性关系(弱这里回归)。 (诚​​然,没有太多的答案,只是一个看起来合理的“评论”。)

标签: r dataframe optimization rbind do.call


【解决方案1】:

这听起来像是 data.table 可以显着加快 (100-1000 倍) 的场景。

https://www.r-bloggers.com/concatenating-a-list-of-data-frames/

Is there a higher order replacement for do.call(rbind, ...)?

如果您将上面的内容替换为以下内容,您的基准测试会说什么:

allgamespbp <- data.table::rbindlist(prebindgames[1:1000]) 

【讨论】:

  • 这绝对是神奇的。我刚刚在 0.22 秒内完成了 rbindlist(prebindgames[1:20000])rbindlist(prebindgames[1:300000]) 在 2.8 秒内。至少出于我的目的,实际上是线性缩放的。我现在无法访问整个列表,但即使需要很长时间,它显然要快多个数量级。谢谢!
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多