我有一个大的双文件(1000万乘500)的CSV文件,我只想阅读这个文件的几千行(在1到1千万之间的不同位置),由二进制向量{{1长度为1000万,如果我不想读取行,则假设值为V
,如果我想读取该行则为0
。
如何从1
包中获取io函数fread
来执行此操作?我问,因为data.table
与所有其他io方法相比如此之快。
此问题的最佳解决方案Reading specific rows of large matrix data file提供了以下解决方案:
fread
其中read.csv( pipe( paste0("sed -n '" , paste0( c( 1 , which( V == 1 ) + 1 ) , collapse = "p; " ) , "p' C:/Data/target.csv" , collapse = "" ) ) , head=TRUE)
是大型CSV文件,C:/Data/target.csv
是V
或0
的向量。
但是我注意到,这比仅在整个矩阵上使用1
要慢几个数量级,即使fread
仅对于V
只有一小部分总行数。
因此,由于整个矩阵上的1
将主导上述解决方案,我如何将fread
(特别是fread
)与行采样结合起来?
这不是重复,因为它只是关于函数fread
。
这是我的问题设置:
fread
答案 0 :(得分:4)
此方法采用向量v
(对应于您的read_vec
),标识要读取的行序列,将这些行提供给fread(...)
的连续调用,以及rbinds
结果一起。
如果您想要的行随机分布在整个文件中,这可能不会更快。但是,如果行是块状(例如c(1:50, 55, 70, 100:500, 700:1500)
),那么对fread(...)
的调用很少,您可能会看到显着的改进。
# create sample dataset
set.seed(1)
m <- matrix(rnorm(1e5),ncol=10)
csv <- data.frame(x=1:1e4,m)
write.csv(csv,"test.csv")
# s: rows we want to read
s <- c(1:50,53, 65,77,90,100:200,350:500, 5000:6000)
# v: logical, T means read this row (equivalent to your read_vec)
v <- (1:1e4 %in% s)
seq <- rle(v)
idx <- c(0, cumsum(seq$lengths))[which(seq$values)] + 1
# indx: start = starting row of sequence, length = length of sequence (compare to s)
indx <- data.frame(start=idx, length=seq$length[which(seq$values)])
library(data.table)
result <- do.call(rbind,apply(indx,1, function(x) return(fread("test.csv",nrows=x[2],skip=x[1]))))