R:快速访问大 CSV 文件的给定行
Posted
技术标签:
【中文标题】R:快速访问大 CSV 文件的给定行【英文标题】:R : Fast access to a given line of a big CSV file 【发布时间】:2018-03-28 08:34:49 【问题描述】:我的数据源是 2GB 文件,由 3 列组成:key1、key2、result。 这些文件由超过 1000 万行组成。 我正在尝试在 Windows 系统上尽可能快地从 R 访问第 j 个文件的第 i 行。 Fread-ing 文件不是一个选项,因为它需要超过 2 分钟,这在这个用例中是不可能的。
我已经尝试了几种方法,但到目前为止都失败了:
方法 1: readlines、read.table 或 fread
readlines(file("myFile.csv", "r"),n=1, skip = M)
read.table("myFile.csv", skip=M, nrows=1)
fread("myFile.csv", skip=M, nrows=1)
这些方法的问题在于,当 M 趋于文件末尾时,访问时间很长。如果能找到类似的解决方案,我会非常感兴趣
方法2: fst包
正如评论/答案部分所建议的,由于From
/ To
参数,fst 包工作正常,但它需要在 FST 格式下复制 CSV,这在阅读时很难维护数千个 CSV 文件。 “基于csv”的解决方案会更好。
方法 3: SQLite DB
library(RSQLite)
library(data.table)
db <- dbConnect(SQLite(), "NEW_DB")
dbWriteTable(db, "chocs", fread("myFile.csv"), append = TRUE, row.names = FALSE)
dbGetQuery(db, "SELECT * FROM chocs WHERE V1 = 1 AND V2 = 1")
这种方法的问题是它创建 SQL DB 而 CSV 已经存在,并且查询不如方法 2 中提出的 FST 库那么快
有什么快速的方法吗?
【问题讨论】:
read.table() 来自基础 R。fread() 来自 data.table。 使用方法 3,在数据加载后类似于dbGetQuery(db, "CREATE INDEX i1 ON chocs (V2, V1)")
并且在批量加载之前不创建主键索引(如 Panagiotis 所述)
主键是一个索引,对于插入的每一行都必须更新。批量加载数据时的一个常见技巧是禁用或删除索引,加载数据然后重建它们。
@NielsouAkbrg SQLite 可以直接使用.import
命令as shown here 导入CSV 文件。之后可以添加索引/主键
看看fstpackage.org
【参考方案1】:
fst
很好,正如我看到 cmets 中提到的@TimSalabim 一样,但是您必须先将其读取,然后将其写入 fst 文件。如果您需要在不同的会话中多次读取任意单行,那么我会说花 2 分钟将其作为具有fread
的数据表一次读取然后将其写为 fst 文件是合理的。
iris
的例子。
library(fst)
library(data.table)
DT <- data.table(iris)
write_fst(DT, "iris.fst")
x <- read_fst("iris.fst", from = 111, to = 111)
x
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 6.5 3.2 5.1 2 virginica
# exit your session, come back tomorrow
library(fst)
x <- read_fst("iris.fst", from = 99, to = 99)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 2.5 3 1.1 versicolor
当然,对你来说,你应该从
DT<- fread("myFile.csv")
write_fst(DT, "myFile.fst")
x <- read_fst("myFile.fst", from = 1e7, to = 1e7)
我现在在一台内存有限的极小机器上,所以我不打算创建一个 2GB 的对象并将其保存以进行测试,但是 iris 示例可以工作,并且一旦您花费了创建文件,您的行读取应该快得多。大概您使用的是一台支持 openMP 和 SSD 的不错的机器。
【讨论】:
我刚刚完成了@TimSalabim 提出的这个精确解决方案的测试,它正在创造奇迹。当 From = M 达到高位时,它的缩放比例非常好!很感动 @NielsouAkbrg 很高兴您找到fts
helpful。我认为它在易于使用和非常快速方面做得很好。如果您觉得这回答了您的问题,请将其标记为答案。如果您觉得它经过了充分的研究和很好的解释,请点赞! ***.com/help/someone-answers
我更新了您的帖子,但原生解决方案会更好。如果没有找到更好的,我会将其标记为 EOD 的答案。【参考方案2】:
data.table
包中的fread
怎么样?行选择可能如下所示:
dt[.(1,1), on = .(V1, V2)]
【讨论】:
是的,在这个时代,2 GB 并不大。正如这个答案所暗示的那样,我只是fread
整个文件。
我确实阅读了整个文件,但耗时太长(大约 2 分钟)。以上是关于R:快速访问大 CSV 文件的给定行的主要内容,如果未能解决你的问题,请参考以下文章
在 R 中访问大型 csv:read.table.ffdf 变慢