使用bigmemory将40 GB csv文件读入R

标题在这里很自我解释,但我会详细说明如下。 我目前攻击这个问题的一些技巧是基于这个问题中提出的解决scheme。 然而,我面临着一些挑战和制约因素,所以我想知道是否有人可能试图对这个问题进行攻击。 我试图找出使用bigmemory软件包的问题,​​但我一直在遇到困难。

目前的限制:

  • 使用16 GB的RAM的Linux服务器
  • 40 GB CSV的大小
  • 行数:67,194,126,114

挑战

  • 需要能够从big.matrix或等同的数据结构中随机抽样更小的数据集(5-10万行)。
  • 需要能够在parsing成big.matrix或等同的数据结构时,删除具有NULL的单个实例的任何行。

到目前为止,结果并不好。 很明显,我在某些方面失败了,也许我只是不太了解大内存文档 。 所以,我想我会问在这里看看有没有人用过

任何提示,build议在这一行的攻击等? 或者我应该改变为别的东西? 我很抱歉,如果这个问题是非常相似的,但我认为按比例的数据比以前的问题大约20倍。 谢谢 !

我不知道bigmemory ,但为了满足你的挑战,你不需要读取文件。只需pipe一些bash / awk / sed / python /任何处理来执行你想要的步骤,即抛出NULL行和随机selectN行,然后读入。

下面是一个使用awk的例子(假设你想从1M行的文件中获得100个随机行)。

 read.csv(pipe('awk -F, \'BEGIN{srand(); m = 100; length = 1000000;} !/NULL/{if (rand() < m/(length - NR + 1)) { print; m--; if (m == 0) exit; }}\' filename' )) -> df 

对于NULL ,我并不清楚你的意思是什么,所以我用字面理解它,但应该很容易修改它以适应你的需求。

这是一个纯粹的R解决scheme来应对大文本文件的采样挑战。 它具有附加的优点,即绘制正好n的随机样本。 它不是太低效率,虽然线被parsing为字符向量,这是相对较慢的。

我们从一个函数签名开始,在这里我们提供一个文件名,我们想要绘制的样本的大小,一个随机数生成器的种子(这样我们就可以再现我们的随机样本!),是否有头的指示行,然后是一个“阅读器”函数,我们将用它来parsing样本到R所看到的对象中,包括额外的参数...读者函数可能需要

 fsample <- function(fname, n, seed, header=FALSE, ..., reader=read.csv) { 

该函数种子随机数发生器,打开连接,并读取(可选)标题行

  set.seed(seed) con <- file(fname, open="r") hdr <- if (header) { readLines(con, 1L) } else character() 

下一步是读取一行n行,初始化所看到的行数的计数器

  buf <- readLines(con, n) n_tot <- length(buf) 

继续读取n行数据块,当没有其他input时停止

  repeat { txt <- readLines(con, n) if ((n_txt <- length(txt)) == 0L) break 

对于每个块,绘制一个n_keep行样本, n_keep行数与当前块中总行数的比例成比例。 这确保了文件中的行被统一采样。 如果没有要保留的行,请移到下一个块。

  n_tot <- n_tot + n_txt n_keep <- rbinom(1, n_txt, n_txt / n_tot) if (n_keep == 0L) next 

select要保留的行和要replace的行,并更新缓冲区

  keep <- sample(n_txt, n_keep) drop <- sample(n, n_keep) buf[drop] <- txt[keep] } 

数据input完成后,我们使用阅读器parsing结果并返回结果

  reader(textConnection(c(hdr, buf), header=header, ...) } 

通过使用readBin和searchR-devel 邮件列表中的 Simon Urbanek所build议的换行符,可以使解决scheme更高效,但更复杂一些。 这是完整的解决scheme

 fsample <- function(fname, n, seed, header=FALSE, ..., reader = read.csv) { set.seed(seed) con <- file(fname, open="r") hdr <- if (header) { readLines(con, 1L) } else character() buf <- readLines(con, n) n_tot <- length(buf) repeat { txt <- readLines(con, n) if ((n_txt <- length(txt)) == 0L) break n_tot <- n_tot + n_txt n_keep <- rbinom(1, n_txt, n_txt / n_tot) if (n_keep == 0L) next keep <- sample(n_txt, n_keep) drop <- sample(n, n_keep) buf[drop] <- txt[keep] } reader(textConnection(c(hdr, buf)), header=header, ...) }