2014-10-30 44 views
0

我有一個體面的大小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')) 

創造一個非常大的data.table的例子好了,所以現在我們有一個data.table與97M行,約1.8Gb。這是我們的出發點。

讓我們刪除值列(熔化後)的所有行, 4

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

最後一行需要大量的內存!在執行此行之前,在我的PC中,內存使用量約爲4.3Gb,在執行該行之後,它將達到6.9Gb!

這是刪除線條的正確方法,對吧? (只是檢查)。有沒有人遇到過這種行爲?

我想循環所有參數,並保持我感興趣的行,在另一個data.table,但不知何故,我懷疑這是一種正確的工作方式。

我期待着您的幫助。

感謝 尼科斯

+0

您只是將1e6 x 1 data.table轉換爲1e6 x 100數據表。 – 2014-10-30 16:54:51

+0

@BonddedDust也許問題不清楚。我將重新提示,但問題是爲什麼刪除行會增加內存使用量。 1e6x100 data.table很好。 – Nikos 2014-10-30 17:47:35

+0

那麼,代碼建議我說,你不是隻創建100倍的數據表,而是100次循環。我想你應該嘗試更小的測試案例來了解真正創建的內容。 – 2014-10-30 17:51:10

回答

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,實現時,都應該是快速和高效存儲。

+0

嗨@阿倫,感謝您的詳細反饋。我不是在追求數學,我只是想知道這種行爲是否是data.table中內部預期的行爲。這是造成一些問題的計算中的最後一步。謝謝。 – Nikos 2014-10-31 09:16:00

+0

嗨@Arun,任何通過引用刪除行的機會是你們將推出的1.9.5/1.9.6版本的下一個特性?對已經很好的data.table,這將是一個很大的改進,恕我直言=) – NoviceProg 2015-03-01 08:50:43