gpt4 book ai didi

使用包 data.table 中的 fread 一次读取 block

转载 作者:行者123 更新时间:2023-12-03 10:27:23 25 4
gpt4 key购买 nike

我正在尝试使用 fread 输入一个大的制表符分隔文件(大约 2GB)包中的函数 data.table .但是,因为它太大了,它不能完全放入内存中。我尝试使用 skip 分块输入它和 nrow论据,例如:

chunk.size = 1e6
done = FALSE
chunk = 1
while(!done)
{
temp = fread("myfile.txt",skip=(chunk-1)*chunk.size,nrow=chunk.size-1)
#do something to temp
chunk = chunk + 1
if(nrow(temp)<2) done = TRUE
}

在上面的例子中,我一次读取 100 万行,对它们进行计算,然后得到下一百万行,等等。这段代码的问题是在检索每个块后, fread需要从头开始扫描文件,因为每次循环迭代后, skip增加一百万。结果,在每个块之后, fread实际到达下一个块需要越来越长的时间,这使得这非常低效。

有没有办法告诉 fread暂停每说 100 万行,然后从那一刻开始继续阅读而不必从头开始?任何解决方案,或者这应该是新功能请求?

最佳答案

您应该使用 LaF包裹。这会在您的数据上引入一种指针,从而避免 - 对于非常大的数据 - 读取整个文件的烦人行为。据我所知 fread()data.table pckg 需要知道总行数,这需要时间处理 GB 数据。
LaF 中使用指针你可以去到你想要的每一行;并读取可以应用函数的数据块,然后继续下一个数据块。在我的小型 PC 上,我以 10e6 行的步长运行了一个 25 GB 的 csv 文件,并提取了总共需要约 5e6 的观察结果——每个 10e6 块需要 30 秒。

更新:

library('LaF')
huge_file <- 'C:/datasets/protein.links.v9.1.txt'

#First detect a data model for your file:
model <- detect_dm_csv(huge_file, sep=" ", header=TRUE)

然后使用模型创建与文件的连接:
df.laf <- laf_open(model)

完成后,您可以执行各种操作,而无需知道 data.table pckgs 中的文件大小。例如,将指针指向第 100e6 行并从此处读取 1e6 行数据:
goto(df.laf, 100e6)
data <- next_block(df.laf,nrows=1e6)

现在 data包含 CSV 文件的 1e6 行(从第 100e6 行开始)。

您可以读取大块数据(大小取决于您的内存)并只保留您需要的内容。例如 huge_file在我的示例中,指向一个包含所有已知蛋白质序列的文件,并且文件大小 > 27 GB - 对我的 PC 来说太大了。为了只获得人类序列,我使用生物体 id 过滤,人类的 9606 应该出现在变量 protein1 的开头。 .一种肮脏的方法是将它放入一个简单的 for 循环中,一次只读取一个数据块:
library('dplyr')
library('stringr')

res <- df.laf[1,][0,]
for(i in 1:10){
raw <-
next_block(df.laf,nrows=100e6) %>%
filter(str_detect(protein1,"^9606\\."))
res <- rbind(res, raw)

}

现在 res包含过滤后的人类数据。但更好 - 对于更复杂的操作,例如实时计算数据 - 函数 process_blocks()将函数作为参数。因此,在函数中,您可以对每条数据做任何你想做的事情。阅读文档。

关于使用包 data.table 中的 fread 一次读取 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19894194/

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