gpt4 book ai didi

读取非常非常大的 NDJSON

转载 作者:行者123 更新时间:2023-12-02 22:57:56 25 4
gpt4 key购买 nike

我有一个 33GB NDJSON 文件,需要读入 R 中的 data.table。它被 gzip 压缩到一个 2GB 文件中,理想情况下我希望将其保持压缩状态。

结构并不那么重要,只是(当通过 jsonlite::stream_in 导入时),我需要的数据仅在几个简单的列中。数据的绝大多数权重都保存在 list 中。我想尽快丢弃三列内的 s。

我的两个挑战是:如何并行化读入,以及如何限制内存使用(现在我处理该文件的工作人员使用 175GB 内存)?

我现在在做什么:

dt.x <- data.table(flatten(stream_in(gzfile("source.gz"))[, -c(5:7)]))

想法:

也许有某种方法可以在 stream_in 期间忽略 NDJSON 的一部分?

我可以解析 gzfile连接,例如使用正则表达式,然后再转到 stream_in ,删除多余的数据?

我可以做类似 readLines 的事情吗?关于gzfile每个worker连接读取100万行数据?

编辑:如果可能的话,我的目标是使其可移植到其他用户并将其完全保留在 R 中。

最佳答案

将 jqr 与 readr 结合使用

以下是说明如何使用 jqr 读取 gzipped NDJSON(又名 JSONL)文件的记录:

$ R --vanilla
> library(readr)
> library(jqr)
> read_lines("objects.json.gz") %>% jq('.a')
[
1,
2,
3
]
>

使用read_file()会产生相同的结果。由于这些函数必须解压缩整个文件,因此内存需求将很大。

分别读取每个 JSON 实体

由于文件是 NDJSON,我们可以通过一次读取一个 JSON 实体来大幅减少所需的 RAM 量:

con = file("objects.json", "r");
while ( length(line <- readLines(con, n = 1)) > 0) {
print( line %>% jq('.a') );
}

jq

可能有更好的方法来使用 jqr,但如果目标是空间和时间效率,那么最好使用 jq 的命令行版本。

计数

如果您需要事先计算(解压缩的)文件中的行数,那么为了节省内存,如果可能的话,我可能会使用 system2wc ;其他所有方法都失败了,您可以运行如下代码片段:

n<-0;
con = file("objects.json", "r");
while (TRUE) {
readLines(con, n = 1);
if (length(line) == 0) { break; }
n <- n+1;
}

关于读取非常非常大的 NDJSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51032141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com