【问题标题】:Spreading very long dataset - performance issues传播非常长的数据集 - 性能问题
【发布时间】:2019-04-09 18:34:27
【问题描述】:

我正在尝试通过具有约 2,000 个唯一值的变量将一个非常长的数据帧(17,000,000 行;111.2MB RDS 文件)传播为宽格式。在 16 核 64GB RAM linux 机器上运行它会产生Error: cannot allocate vector of size 3132.3GB

下面的dplyrcode 完美地适用于较小的数据集(约 1/3 大小)。

data <- data %>%
  rowid_to_column() %>%
  spread(key = parameter_name, value = value) %>%
  select(-rowid)

有什么办法可以完成这项工作吗?更高效的编码?

【问题讨论】:

  • 你能提供一些数据来运行你的代码吗?您是否尝试过使用 {data.table} 的等效解决方案?
  • 正如@markus 链接中的一个cmets 中所建议的那样(公平地说,我的评论):如果您的数据相当大,可能需要split,单独重塑每个元素,然后以某种方式重新组合。重新组合时必须注意确保列和行正确对齐,但在大方案中这是最小的努力。
  • 你也可以试试widyrgithub.com/dgrtwo/widyr

标签: r performance dplyr spread


【解决方案1】:

在我看来,您正在尝试创建 17e6 x 2000 的 data.frame,这是非常不合理的(因为每一行只有一个值)。

如果您的值是整数,则生成的 data.frame 的大小为:

v <- sample.int(17e6)
format(object.size(v) * 2000, units = 'Gb')
# [1] "126.7 Gb"

或双倍:

v <- rnorm(17e6)
format(object.size(v) * 2000, units = 'Gb')
# [1] "253.3 Gb"

您也许应该研究稀疏矩阵或重新考虑您在做什么。

使用 data.table 的 200k x 2000 测试用例:

N <- 200000
n <- 2000
require(data.table)
dt <- data.table(parameter_name = sample.int(n, N, T), value = rnorm(N), id = 1:N)
r <- dcast(dt, id ~ parameter_name)
format(object.size(r), units = 'Gb')
# [1] "3 Gb"

结果已在 3GB 中。

【讨论】:

    【解决方案2】:

    虽然 dplyr 更方便,但 data.table 转换更节省内存且速度更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-08
      • 2011-02-04
      • 2019-06-29
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      相关资源
      最近更新 更多