【问题标题】:R's data.table crashing upon subset of factors for large dataR 的 data.table 因大数据的因子子集而崩溃
【发布时间】:2020-05-13 17:53:30
【问题描述】:

我有一个相对较大的 data.table(大约 10 亿行和 30 列),并且正在尝试对其进行子集化以删除一些我不感兴趣的类别。category 变量是一个大约 30标签。但是,当我这样做时,我的会话一直被杀死。有没有办法对 data.table 进行子集化?

鉴于我的 data.table 是 dt,导致崩溃的行是:

dt <- dt[!category %in% c('f', 'g')]

关于如何避免此问题的任何建议?抱歉,没有一个可重复的例子,这种规模的数据显然很难。我正在使用 R 版本 3.6.1 和 data.table 版本 1.12.9。

【问题讨论】:

  • 有没有办法对 data.table 进行子集化? data.table can't delete rows by reference yet
  • 您是否尝试过基于二进制搜索的“不加入子集”dt[!c('f', 'g'), on = "category"]。另见2。在小插图Secondary indices and auto indexing 中使用参数和二级索引进行快速子集化
  • 我之前没有尝试过“不加入子集” - 这解决了问题,感谢@Henrik!
  • 好!另请参阅?data.table 中的示例部分:# joins as subsets# fast *keyed* subsets。干杯。
  • NOT IN 以前在 SQL 中效率很低,也许这里也有效

标签: r data.table


【解决方案1】:

我尝试了一些 5 亿行和 5 列的方法。

通过一些优化,我将内存分配提高了大约 8%:

编辑:您可以通过@Henrik 的建议再获得 3-4%。

library(data.table)
library(bench)
set.seed(3)
#sample.size <- 500000000 #Don't try this on your home laptop folks
sample.size <- 1000000
test.dt <- data.table(category = sample(as.factor(letters),size = sample.size, replace = TRUE),
                      as.data.table(lapply(1:5,function(x)as.integer(runif(sample.size,1,100)))))

mark(result <- test.dt[!category %in% c('f', 'g')],
     result <- test.dt[!(category == 'f' | category == 'g')],
     result <- test.dt[!c('f','g'),on = "category"])


 expression                                                   min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time 
  <bch:expr>                                              <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
1 result <- test.dt[!category %in% c("f", "g")]             18.15s   18.15s    0.0551    23.2GB    0.110     1     2     18.15s
2 result <- test.dt[!(category == "f" | category == "g")]    8.43s    8.43s    0.119     21.3GB    0.119     1     1      8.43s
3 result <- test.dt[!c("f", "g"), on = "category"]           7.83s    7.83s    0.128     20.6GB    0.383     1     3      7.83s

【讨论】:

  • 这解决了问题!非常感谢@Ian Campbell - 我认为效率的提高足以避免我正在使用的服务器超载。
  • 您知道mem_alloc 没有反映实际内存使用情况吗?
  • 你有什么更好的建议?
  • 谢谢你的链接,我去看看。我不确定实施准确测试的努力是否值得。 bench::mark 提供的任何替代物至少似乎反映了相对的改进。
  • 不值得,但它并没有使 bench::mark 内存测量不准确。
猜你喜欢
  • 2019-10-06
  • 2012-04-29
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多