【发布时间】:2014-03-14 23:15:51
【问题描述】:
我有一个双精度的大 CSV 文件(1000 万乘 500),我只想读取这个文件的几千行(在 1 到 1000 万之间的不同位置),由二进制向量 V 定义长度为 1000 万,如果我不想阅读该行,则假定值为 0,如果我想阅读该行,则假定值为 1。
如何从 data.table 包中获取 io 函数 fread 来执行此操作?我之所以问是因为与所有其他 io 方法相比,fread 是如此之快。
这个问题的最佳解决方案,Reading specific rows of large matrix data file,给出了以下解决方案:
read.csv( pipe( paste0("sed -n '" , paste0( c( 1 , which( V == 1 ) + 1 ) , collapse = "p; " ) , "p' C:/Data/target.csv" , collapse = "" ) ) , head=TRUE)
其中C:/Data/target.csv 是大型CSV 文件,V 是0 或1 的向量。
但是我注意到这比在整个矩阵上简单地使用 fread 慢几个数量级,即使 V 将仅等于 1 用于总行数的一小部分。
因此,由于整个矩阵上的fread 将主导上述解决方案,我如何将fread(特别是fread)与行采样结合起来?
这不是重复的,因为它只是关于函数fread。
这是我的问题设置:
#create csv
csv <- do.call(rbind,lapply(1:50,function(i) { rnorm(5) }))
#my csv has a header:
colnames(csv) <- LETTERS[1:5]
#save csv
write.csv(csv,"/home/user/test_csv.csv",quote=FALSE,row.names=FALSE)
#create vector of 0s and 1s that I want to read the CSV from
read_vec <- rep(0,50)
read_vec[c(1,5,29)] <- 1 #I only want to read in 1st,5th,29th rows
#the following is the effect that I want, but I want an efficient approach to it:
csv <- read.csv("/home/user/test_csv.csv") #inefficient!
csv <- csv[which(read_vec==1),] #inefficient!
#the alternative approach, too slow when scaled up!
csv <- fread( pipe( paste0("sed -n '" , paste0( c( 1 , which( read_vec == 1 ) + 1 ) , collapse = "p; " ) , "p' /home/user/test_csv.csv" , collapse = "" ) ) , head=TRUE)
#the fastest approach yet still not optimal because it needs to read all rows
require(data.table)
csv <- data.matrix(fread('/home/user/test_csv.csv'))
csv <- csv[which(read_vec==1),]
【问题讨论】:
标签: r csv io performance