【问题标题】:read.csv is extremely slow in reading csv files with large numbers of columnsread.csv 在读取具有大量列的 csv 文件时非常慢
【发布时间】:2011-11-11 18:34:08
【问题描述】:

我有一个 .csv 文件:example.csv 包含 8000 列 x 40000 行。 csv 文件的每一列都有一个字符串标题。所有字段都包含 0 到 10 之间的整数值。当我尝试使用 read.csv 加载此文件时,结果非常慢。当我添加一个参数nrow = 100时,它也很慢。我想知道是否有办法加速 read.csv,或者使用其他函数而不是 read.csv 将文件作为矩阵或 data.frame 加载到内存中?

提前致谢。

【问题讨论】:

  • 请分享您用于 read.csv 的代码 - 有很多选项可以提高性能,请参阅 ?read.table

标签: r csv


【解决方案1】:

如果您的 CSV 仅包含整数,则应使用 scan 而不是 read.csv,因为 ?read.csv 表示:

 ‘read.table’ is not the right tool for reading large matrices,
 especially those with many columns: it is designed to read _data
 frames_ which may have columns of very different classes.  Use
 ‘scan’ instead for matrices.

由于您的文件有一个标题,您将需要skip=1,如果您设置what=integer(),它可能会更快。如果您必须使用read.csv 并且速度/内存消耗是一个问题,那么设置colClasses 参数将有很大帮助。

【讨论】:

  • 您可以通过使用 readLines() 函数将标题的单行读取为向量并修改矩阵的列名来添加列名。
  • 谢谢。我刚刚发现另一个使用 scan() 的包装函数:tseries 包中的 read.matrix 函数。它声称它比 read.csv 更快。
【解决方案2】:

尝试使用data.table::fread()。这是迄今为止将.csv 文件读入R 的最快方法之一。有一个good benchmark here

library(data.table)

data <- fread("c:/data.csv")

如果你想让它更快,你也可以只读取你想使用的列的子集:

data <- fread("c:/data.csv", select = c("col1", "col2", "col3"))

【讨论】:

  • fread 在我的数据上立即崩溃(有一百万多列)
  • 这很奇怪;我建议您卸载并重新安装库: ´remove.packages("data.table") ; install.packages("data.table")´ 。如果问题仍然存在,您可能需要考虑在项目网站github.com/Rdatatable/data.table/wiki 上打开一个“问题”
  • 即时崩溃似乎表明您没有足够的可用内存来读取数据。
【解决方案3】:

也可以试试 Hadley Wickham 的 readr 包:

library(readr) 
data <- read_csv("file.csv")

【讨论】:

    【解决方案4】:

    如果您经常阅读该文件,则可能值得使用save 函数将其从R 中以二进制格式保存。指定 compress=FALSE 通常会加快加载速度。

    ...然后您可以使用(惊喜!)load 函数加载它。

    d <- as.data.frame(matrix(1:1e6,ncol=1000))
    write.csv(d, "c:/foo.csv", row.names=FALSE)
    
    # Load file with read.csv
    system.time( a <- read.csv("c:/foo.csv") ) # 3.18 sec
    
    # Load file using scan
    system.time( b <- matrix(scan("c:/foo.csv", 0L, skip=1, sep=','), 
                             ncol=1000, byrow=TRUE) ) # 0.55 sec
    
    # Load (binary) file using load
    save(d, file="c:/foo.bin", compress=FALSE)
    system.time( load("c:/foo.bin") ) # 0.09 sec
    

    【讨论】:

    • 压缩速度是否取决于多种因素,可以在 /file /machine 基础上进行测试。 HD 速度、CPU 速度和所达到的压缩程度都决定了压缩文件还是未压缩文件的加载速度更快。但一般来说,当驱动器速度良好而 CPU 速度不是时,未压缩的速度会更快,而压缩后的情况则相反。例如,我倾向于在高速笔记本电脑上使用压缩写入 USB 闪存驱动器。
    【解决方案5】:

    可能值得尝试新的vroom

    vroom 是一种将定界和固定宽度数据读入 R 的新方法。

    这源于观察分析文件时从磁盘读取数据并找到分隔符通常不是主要瓶颈。取而代之的是(重新)分配内存并将值解析为 R 数据类型(尤其是字符)会占用大量时间。

    因此,您可以通过首先执行快速索引步骤,然后使用 R 版本 3.5+ 中提供的ALTREP (ALternative REPresentations) 框架以惰性/延迟方式访问值来获得非常快速的输入。

    这种方法还可能允许您处理大于内存的数据。只要您小心避免一次将整个数据集具体化,就可以有效地对其进行查询和子集化。

    #install.packages("vroom", 
    #                 dependencies = TRUE, repos = "https://cran.rstudio.com")
    library(vroom)
    
    df <- vroom('example.csv')
    

    Benchmark: readr vs data.table vs vroom 对于 1.57GB 文件

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      相关资源
      最近更新 更多