2

我有一个包含 31 个 gzip 压缩 TSV(2.8 GB 压缩/40 GB 未压缩)的目录。我想根据 1 列的值有条件地导入所有匹配的行,并组合成一个数据框。

我在这里阅读了几个答案,但似乎没有一个有效 - 我怀疑它们不适合处理那么多数据。

简而言之,我该如何:

  1. 读取 3 GB 的 gzip 文件
  2. 仅导入其列与某个值匹配的行
  3. 将匹配的行合并到一个数据框中。

数据很整齐,只有 4 列感兴趣:日期、ip、类型(str)、类别(str)。

我尝试使用的第一件事read_tsv_chunked()

library(purrr)
library(IPtoCountry)
library(lubridate)
library(scales)
library(plotly)
library(tidyquant)
library(tidyverse)
library(R.utils)
library(data.table)

#Generate the path to all the files.
import_path <- "import/"
files <-  import_path %>% 
  str_c(dir(import_path))

#Define a function to filter data as it comes in.
call_back <- function(x, pos){
  unique(dplyr::filter(x, .data[["type"]] == "purchase"))
}

raw_data <- files %>%
  map(~ read_tsv_chunked(., DataFrameCallback$new(call_back),
      chunk_size = 5000)) %>%
  reduce(rbind) %>%
  as_tibble() # %>%

第一种方法适用于 9 GB 的未压缩数据,但不适用于 40 GB。

fread()使用(相同加载的包)的第二种方法:

 #Generate the path to all the files.
    import_path <- "import/"
    files <-  import_path %>% 
      str_c(dir(import_path))

 bind_rows(map(str_c("gunzip - c", files), fread))

看起来它开始工作了,但后来被锁定了。我无法弄清楚如何将select = c(colnames)参数传递到/调用fread()内部,更不用说一列的过滤条件了。map()str_c()

4

2 回答 2

3

这更像是一个策略答案。

R 将所有数据加载到内存中进行处理,因此您会遇到正在查看的数据量的问题。

我建议你做的,也就是我做的,是使用 Apache Spark 进行数据处理,并使用 R 包 sparklyr 来连接它。然后,您可以将数据加载到 Spark 中,在那里对其进行处理,然后将汇总的数据集检索回 R 中以进行进一步的可视化和分析。

您可以在 R Studio 实例中本地安装 Spark,并在那里做很多事情。如果您需要更多计算能力,请查看 AWS 等托管选项。

阅读此https://spark.rstudio.com/

一个技术点,有一个sparklyr函数spark_read_text可以将分隔的文本文件直接读取到 Spark 实例中。它非常有用。

从那里你可以dplyr用来操作你的数据。祝你好运!

于 2018-10-24T01:25:26.620 回答
1

首先,如果使用基本的read.table,你不需要gunzip任何东西,因为它使用 Zlib 直接读取这些。如果指定了colClasses参数,read.table的运行速度也会更快。

你可能需要编写一些自定义的R代码来直接从 31 个 TSV 中的每一个生成一个融合的数据帧,然后通过rbind来累积它们。

拥有一台具有大量快速虚拟内存的机器仍然会有所帮助。我经常按这个顺序处理数据集,有时我发现一个 Ubuntu 系统需要内存,即使它有 32 个内核。我有一个替代系统,我让操作系统相信 SSD 是它的更多内存,给我一个有效的 64 GB RAM。我发现这对于其中一些问题非常有用。它是 Windows,所以我需要适当地设置memory.limit(size=...)

请注意,一旦使用read.table读取 TSV ,它就会非常压缩,接近gzip提供的内容。如果你这样做,你可能不需要一个大系统。

如果结果证明需要很长时间(我对此表示怀疑),请务必在两者之间的位置检查点和save.image

于 2019-04-13T20:09:28.440 回答