首页 > 解决方案 > 按列合并大型 CSV 行时的内存问题

问题描述

问题

有一个1G 的 CSV文件,包含40 列330 万行:

DT
   ID a  b  c  d ...
1:  b 1  7 13 19
2:  b 2  8 14 20
3:  b 3  9 15 21
4:  a 4 10 16 22
5:  a 5 11 17 23
6:  c 6 12 18 24
...

我需要按列合并行(我们称之为ID):

outDT
   ID a  b        c        d ...
1:  b 3  9 13,14,15 19,20,21
2:  a 5 11    16,17    22,23
3:  c 6 12       18       24
...

某些列只能存储单个值(后续行覆盖前一行)。其余列被视为多值(单元格应分组到列表中)。

我试过的

以下代码段适用于小型数据集:

library("data.table")
DT <- data.table(ID = c("b","b","b","a","a","c"), a = 1:6, b = 7:12, c = 13:18, d = 19:24)
DT
#   ID a  b  c  d
#1:  b 1  7 13 19
#2:  b 2  8 14 20
#3:  b 3  9 15 21
#4:  a 4 10 16 22
#5:  a 5 11 17 23
#6:  c 6 12 18 24

id <- "ID"
overwriteCols <- c("a", "b")
groupCols <- names(DT)[!names(DT) %in% c(overwriteCols, id)]

DTo <- DT[, lapply(.SD, last), by = id, .SDcols = overwriteCols]
DTg <- DT[, lapply(.SD, (function(x) x = list(x))), by = id, .SDcols = groupCols]
outDT <- DTo[DTg, on = id]
outDT
#   ID a  b        c        d
#1:  b 3  9 13,14,15 19,20,21
#2:  a 5 11    16,17    22,23
#3:  c 6 12       18       24

但是当将示例数据表替换为真实表时,它会出现内存不足的问题:

id <- "PROVIDER_ID"
dropCols <- c(
  # ...
)
DT <- fread(path,
            header = T,
            sep="|",
            stringsAsFactors = T,
            blank.lines.skip = T,
            nThread = 3,
            fill = T,
            drop = dropCols,
            key = c("PROVIDER_ID"))

对操作groupCols要求特别高。我尝试将操作链接到overwriteColsand groupCols,但分组本身似乎太重了。4G该脚本因我的笔记本电脑上的内存限制而失败。

我想到了分块处理,但我想不出任何可行的解决方案。

问题

如何使我的代码更节省内存?

标签: rcsvoptimizationdata.tableout-of-memory

解决方案


推荐阅读