我有一个由双精度浮点数组成的大型CSV文件(10百万行,每行500列),我只想读取其中几千行数据(位于1百万到10百万之间的不同位置),这些行由长度为10百万的二进制向量V定义,如果我不想读取该行,则V的值为0,如果我想读取该行,则V的值为1。
我该如何使用data.table包中的io函数fread来实现?我询问是因为与所有其他io方法相比,fread速度非常快。
该问题的最佳解决方案Reading specific rows of large matrix data file提供了以下解决方案:
我该如何使用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
组成的向量。
然而我发现,即使对于总行数只有一小部分为 1
的情况,使用整个矩阵的 fread
相比之下要慢几个数量级。
因此,由于整个矩阵的 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),]
apply
函数花了一些时间,但是这是一个很好的学习机会。@jlhoward - Lazarus Thurston