我有一个50K列,500K行的矩阵,我想通过列名/索引快速地将其子集,而不需要使用太多内存(例如,内存映射)。大多数列是{NA,1,2},少数(1%)列是数量或字符串。R中的哪些文件格式/框架最适合这样做?
我想我可以使用feather来完成这项工作,但它似乎加载了整个文件,并且使用的内存几乎与data.table一样多。等同的,即使我设置了as_data_frame=F。
f="/path/to/matrix.50Kcolums.500Krows.tsv"
df <- data.table::fread(f) #
arrow::write_feather(df,paste0(f,".feather"))
df <- read_feather(f.arrow, as_data_frame = FALSE) # uses almost as much memory as fread()
df <- as.data.frame(df[,grep("columns_with_some_name", names(df))]) # this is what I need it to do fast and without using much memory. 有什么想法吗?
发布于 2021-05-12 23:44:11
@Jon Keane是正确的。使用col_select应该可以让您实现这一点。
(conbench2) pace@pace-desktop:~/dev/arrow/r$ /usr/bin/time -v Rscript -e "print(arrow::read_feather('/home/pace/dev/data/feather/big/data.feather', col_select=c('f0', 'f7000', 'f32000'), as_data_frame = FALSE))"
Table
500000 rows x 3 columns
$f0 <int32>
$f7000 <int32>
$f32000 <int32>
Command being timed: "Rscript -e print(arrow::read_feather('/home/pace/dev/data/feather/big/data.feather', col_select=c('f0', 'f7000', 'f32000'), as_data_frame = FALSE))"
User time (seconds): 1.16
System time (seconds): 0.51
Percent of CPU this job got: 150%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.11
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 262660
Average resident set size (kbytes): 0
...也就是说,当整个文件无法装入内存时,feather可能不是最好的格式。在这种情况下,即使您指定了内存映射,您仍然必须执行I/O。如果您一次又一次地重复访问相同的一小部分列,则应该没问题。它们将被快速加载到页面缓存中,并且I/O成本将消失。
另一方面,如果您每次都访问随机列,或者您希望在两次运行之间有很大的时间间隔(在这种情况下,页面将不在页面缓存中),则可以考虑使用parquet。拼接将需要更多的CPU时间来压缩/解压缩,但应该会减少需要加载的数据量。当然,对于相对较少的数据量(例如,该数据集的0.2% ),性能上的差异可能会非常小。即使这样,它也可能会节省您的硬盘空间,因为您所描述的表占用了大约100 is的空间,而且由于“大多数列都是{NA,1,2}”,我希望数据是高度可压缩的。
https://stackoverflow.com/questions/67501437
复制相似问题