【问题标题】:fread takes a lof of memory when "skip" is large当“skip”很大时,fred 会占用大量内存
【发布时间】:2018-06-12 10:54:10
【问题描述】:

我有一个很大的 csv 文件(20G,将近 2 亿行),我无法将它作为一个整体加载到内存中----> 所以我想逐个加载它。

我没有找到在 fread 中使用文件连接的方法(就像在 readLines 中那样)----> 所以我尝试使用“skip”:

for(i in 1:100){
lines=fread(filename,nrows=rowPerRead,skip=(i-1)*rowPerRead)
}

这在开始时效果很好。但随着跳跃变大,它会变慢——以非线性方式。事实证明,尽管跳过了这些行,但在此过程中仍会占用大量内存,并且仅在该过程完成后才会被清理。而且一旦内存用完,这个过程就会变得很慢。

> system.time({newLines=fread("userinfo4.csv",nrows=1e6,skip=1,quote="") })
   user  system elapsed 
   0.71    0.04    0.73 
> system.time({newLines=fread("userinfo4.csv",nrows=1e6,skip=1e8,quote="") })
Read 1000000 rows and 12 (of 12) columns from 20.049 GB file in 00:01:47
   user  system elapsed 
  21.89   13.76  106.60 
> system.time({newLines=fread("userinfo4.csv",nrows=1e6,skip=1.4e8,quote="") })
Read 1000000 rows and 12 (of 12) columns from 20.049 GB file in 00:02:48
   user  system elapsed 
  16.95   12.49  169.76 
> 

第 2 次和第 3 次运行的内存使用情况。

所以我的问题是: 1. 有没有一种内存效率更高的方式来运行大跳过的 fread? 2.有没有办法从文件连接运行 fread ---所以我可以从最后一次读取继续,而不是从头开始。

【问题讨论】:

  • 您是否尝试在将文件加载到 R 之前将其拆分为较小的块?
  • 是的,我就是这样处理的。不幸的是,我不知道有什么更好的工具来分割文件,所以我在 R 中使用了 readLines+writeLines,这比 fread 慢得多。
  • 在命令行你可以使用“split”。应该在类 Unix 系统上可用或易于安装。在 Windows 上可能会更难。
  • 您可能已经从帖子中的 img 中注意到了这一点,这是任务管理器,我是一个愚蠢的 windows 用户....可能这就是为什么一切对我来说都如此困难的原因:)跨度>
  • 上次我必须使用 Windows 我安装了msys2.org。今天docs.microsoft.com/en-us/windows/wsl/install-win10 可能会更轻松。

标签: r csv data.table


【解决方案1】:

我使用data.table::fread 在跳过行时以块的形式读取数据时遇到了同样的问题。根据我的经验,添加garbage collection 步骤有助于解决此问题。 (虽然 R 应该在需要内存时自动调用 base::gc(),但由于某种原因,在循环中使用了 data.table::fread,它似乎无法有效地工作。)

在您的示例代码中,它看起来像这样:

for(i in 1:100){
lines=fread(filename,nrows=rowPerRead,skip=(i-1)*rowPerRead)
gc()
}

【讨论】:

  • 很有趣,感谢您提供的信息。我不知道 R 有一个 gc()。
【解决方案2】:

您可以使用fread 的功能来接受将文件预处理为输入的shell 命令。使用此选项,我们可以运行 gawk 脚本来提取所需的行。请注意,如果您的系统上尚未安装 gawk(Linux 和类似 Unix 的机器通常已经安装了它,在 Windows 上您可能需要安装它),您可能需要安装它。

n = 100   # lines to skip
cmd = paste0('gawk "NR > ', n, '" ', filename)
lines = fread(cmd, nrows = rowPerRead)

【讨论】:

  • 没有尝试过,因为gawk看起来很强大,我需要一些时间来熟悉它。但是使用 cmd 肯定会打开很多可能性,所以我会接受这个答案。非常感谢。
猜你喜欢
  • 2014-05-11
  • 2011-02-27
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多