删除data.table中的行并增加内存使用量

时间:2014-10-30 16:51:52

标签: r memory memory-leaks data.table

我有一个相当大的89M行,3.7Gb的data.table。钥匙就位,所以一切都设置正确。但是,当我根据列的值删除行时遇到问题。内存使用率只是通过屋顶!

仅仅为了记录,我已经阅读了其他关于此的帖子,但他们并没有真正帮助太多。此外,我正在使用RStudio,我很确定它并不理想,但它在试验时有所帮助,但是我注意到R控制台中的相同行为。我正在使用Windows。

让我发一个例子(取自关于删除行的类似问题)创建一个非常大的数据。表格约1e6x100

rm(list=ls(all=TRUE))               #Clean stuff
gc(reset=TRUE)                      #Call gc (not really helping but whatever..)
dimension=1e6                       #let's say a million
DT = data.table(col1 = 1:dimension)
cols = paste0('col', 2:100)         #let these be conditions as columns
for (col in cols){ DT[, col := 1:dimension, with = F] }
DT.m<-melt(DT,id=c('col1','col2','col3')) 

好的,现在我们有一个97M行的数据表,大约1.8Gb。这是我们的出发点。

让我们删除值列(融化后)所在的所有行。 4

DT.m<-DT.m[value!=4]

最后一行需要大量内存!在执行此行之前,在我的PC中,内存使用量约为4.3Gb,在执行该行后,它将达到6.9Gb!

这是删除线条的正确方法,对吗? (只是检查)。有没有人遇到过这种行为?

我想到了循环所有参数并保留我感兴趣的行,在另一个data.table中,但不知怎的,我怀疑这是一种正确的工作方式。

我期待着你的帮助。

由于 尼科斯

1 个答案:

答案 0 :(得分:3)

更新:使用this commit,逻辑向量将被行索引替换以节省内存(请阅读下面的帖子以获取更多信息)。修正于1.9.5。


执行sum(DT.m$value == 4L)会给我97。也就是说,你从9700万行中删除了总共97行。这反过来意味着子集操作也会返回~1.8GB的数据集。

  • 开头的内存使用量为4.3GB
  • 您提供的条件value == 4占用的逻辑向量空间为9700万= = 360MB。
  • data.table计算which(that_value)以获取索引=几乎所有行=另一个360MB
  • 作为子集的数据必须先在其他地方分配,那是~1.8GB。

总计达到4.3 + 1.8 + 0.72 = ~6.8GB

垃圾收集还没有发生。如果您现在执行gc(),则应释放与旧DT.m对应的内存。

我能看到的唯一可以节省空间的地方是用整数向量替换逻辑向量(而不是将整数索引存储在另一个向量中)以节省额外的360MB空间。

通常which会产生一个小得多(可忽略不计)的值 - 因此子集更快 - 这就是使用which()的原因。但在这种情况下,您删除97行。

但很高兴知道我们可以节省一点内存。您能否提出问题here

Removing rows by reference, #635,一旦实施,应该既快速又节省内存。